Thread: Reversing a line at a time !

  1. #1
    Registered User Jeet's Avatar
    Join Date
    Jan 2013
    Posts
    7

    Unhappy Reversing a line at a time !

    Well I was solving the K&R problem - Write a function reverse(s) that reverses the character string s . Use it to write a program that reverses its input a line at a time. I got the first part correct but when I tried to modify to accommodate the second part the results aren't as intended. I know I screwed up somewhere in the array index calculation, but can't make it right ! Please help ! Here's my code so far:

    Code:
    #include <stdio.h>
    #define MAXLINE 1000
    
    
    void getline(char[], int);
    int main()
    {
    	char line[MAXLINE];
    	getline(line, MAXLINE);
    	printf("%s", line);
    	return 0;
    }
    void getline(char s[], int maxlen)
    {
    	int arrayLength, c, temp, i, preLen = 0;
    	for(arrayLength = 0; arrayLength  < maxlen-1 && (c = getchar()) != EOF; arrayLength++)
    	{
    		if(c == '\n')
    		{
    		    s[arrayLength] = '\n';
    			for(i = preLen; i < (arrayLength+preLen)/2; i++)
    			{
    				temp = s[i];
    				s[i] = s[arrayLength - i - 1];
    				s[arrayLength - i - 1] = temp;
    			}
    			preLen += arrayLength;
    		}
    		else
    		{
    			s[arrayLength] = c;
    		}
    	}
    	s[arrayLength--] = '\0';
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Perhaps your main should read
    Code:
        getline(line, MAXLINE);
        reverseline(line);
        printf("%s", line);
    Don't cram unrelated functionality into getline.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User Jeet's Avatar
    Join Date
    Jan 2013
    Posts
    7
    Quote Originally Posted by Salem View Post
    Perhaps your main should read
    Code:
        getline(line, MAXLINE);
        reverseline(line);
        printf("%s", line);
    Don't cram unrelated functionality into getline.
    Made two functions and almost solved the problem but there's a small snag. One of my inputs token gets skipped ! Why is it behaving like that?

    Code:
    #include <stdio.h>#include <stdlib.h>
    #define MAXLINE 1000
    void reverseLine(char[], int);
    int getline(char[], int);
    int main()
    {
        int len,c;
    	char line[MAXLINE];
    	while((c = getchar()) != EOF)
        {
            len = getline(line, MAXLINE);
            reverseLine(line, len);
            printf("%s\n", line);
        }
    	return 0;
    }
    int getline(char s[], int maxlen)
    {
    	int str, c;
    	for(str = 0; str < maxlen-1 && (c = getchar()) != EOF && c != '\n'; str++)
    	{
            s[str] = c;
    	}
    	if(c == '\n')
        {
            s[str] = '\0';
        }
    	return str;
    }
    void reverseLine(char s[], int len)
    {
        int i, temp;
        for(i = 0; i < len/2; i++)
        {
            temp = s[i];
            s[i] = s[len - i - 1];
            s[len - i - 1] = temp;
        }
    }
    Thanks !

  4. #4
    Stoned Witch Barney McGrew's Avatar
    Join Date
    Oct 2012
    Location
    astaylea
    Posts
    420
    Well, you don't need to call getchar at all in main. You should return EOF from getline when it reads it (and the buffer's empty), so that you can use it like this:

    Code:
    while ((len = getline(line, MAXLINE)) != EOF) { reverseLine(line, len); puts(line); }
    See any implementation of fgets if you have trouble doing this, since it works in a similar way.

  5. #5
    Registered User Jeet's Avatar
    Join Date
    Jan 2013
    Posts
    7
    Quote Originally Posted by Barney McGrew View Post
    Well, you don't need to call getchar at all in main. You should return EOF from getline when it reads it (and the buffer's empty), so that you can use it like this:

    Code:
    while ((len = getline(line, MAXLINE)) != EOF) { reverseLine(line, len); puts(line); }
    See any implementation of fgets if you have trouble doing this, since it works in a similar way.
    Works perfectly ! Now I get it ! It was the getchar() that ate my last character. Thanks for clearing it out ! I can't use fgets as it is not yet introduced in the text. Thanks for the help .

  6. #6
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    The way getline is defined in K&R, the return value should be 0 (not EOF) in the case that no more lines can be read. This is because getline assumes that a minimal line has a length of 1. The authors also mention that you can also implement getline by just calling fgets:

    Code:
    /* getline: read a line, return length*/
    int getline(char *line, int max)
    {
      if (fgets(line, max, stdin) == NULL)
        return 0;
      else
        return strlen(line);
    }

  7. #7
    Stoned Witch Barney McGrew's Avatar
    Join Date
    Oct 2012
    Location
    astaylea
    Posts
    420
    His function discards the newline character, so it returns 0 and stores an empty string with empty lines. I'd say EOF (or any negative integer value) is a good choice for his particular function.

  8. #8
    Registered User Jeet's Avatar
    Join Date
    Jan 2013
    Posts
    7
    Quote Originally Posted by c99tutorial View Post
    The way getline is defined in K&R, the return value should be 0 (not EOF) in the case that no more lines can be read. This is because getline assumes that a minimal line has a length of 1. The authors also mention that you can also implement getline by just calling fgets:

    Code:
    /* getline: read a line, return length*/
    int getline(char *line, int max)
    {
      if (fgets(line, max, stdin) == NULL)
        return 0;
      else
        return strlen(line);
    }
    My getline() is the bare minimum version as described in the first chapter. It's not the more advanced implementation.

  9. #9
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by Jeet View Post
    My getline() is the bare minimum version as described in the first chapter.
    Which edition of the book are you using? In the second edition, the getline() function presented is guaranteed to null-terminate the string. However, your version will only null-terminate it in the case that '\n' is encountered.

  10. #10
    Registered User Jeet's Avatar
    Join Date
    Jan 2013
    Posts
    7
    Quote Originally Posted by c99tutorial View Post
    Which edition of the book are you using? In the second edition, the getline() function presented is guaranteed to null-terminate the string. However, your version will only null-terminate it in the case that '\n' is encountered.
    You are correct, however not null terminating was my choice not K&R's style.

  11. #11
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    You can define it that way if you want. But a potential problem is that some apparently correct uses are undefined

    Code:
    int main(void) {
      char s[100];
      if (getline(s, 100) > 0)
        printf("`%s'\n", s);
      return 0;
    }
    If you run this program with some input "abc" which is missing a newline character using K&R's getline(), the output is `abc'. Substituting your version means the output will be undefined. In other words, your version will print `abc??????...' where ??? are random characters in memory, one of which may or may not happen to be a null-terminator that was already hanging around in memory.

  12. #12
    Registered User Jeet's Avatar
    Join Date
    Jan 2013
    Posts
    7
    Quote Originally Posted by c99tutorial View Post
    You can define it that way if you want. But a potential problem is that some apparently correct uses are undefined

    Code:
    int main(void) {
      char s[100];
      if (getline(s, 100) > 0)
        printf("`%s'\n", s);
      return 0;
    }
    If you run this program with some input "abc" which is missing a newline character using K&R's getline(), the output is `abc'. Substituting your version means the output will be undefined. In other words, your version will print `abc??????...' where ??? are random characters in memory, one of which may or may not happen to be a null-terminator that was already hanging around in memory.
    Duly noted. But actually my assignment was to replace the null terminator with a newline, the K&R question was a standard of how reversal should be handled.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 06-07-2012, 02:50 AM
  2. Replies: 7
    Last Post: 12-13-2010, 02:13 PM
  3. how get a whole line of file every time
    By zcrself in forum C++ Programming
    Replies: 2
    Last Post: 03-29-2010, 08:51 PM
  4. Replies: 3
    Last Post: 04-30-2007, 09:53 AM
  5. Reading one line at a time...
    By lala123 in forum C Programming
    Replies: 12
    Last Post: 07-08-2005, 09:01 PM

Tags for this Thread