Is there an off-by-one error in this example code?

This is a discussion on Is there an off-by-one error in this example code? within the C Programming forums, part of the General Programming Boards category; Right, so in a K&R exercise, I'm supposed to modify this code (which I haven't touched yet). It currently uses ...

  1. #1
    Registered User edw211's Avatar
    Join Date
    Jun 2011
    Location
    Wilkes-Barre, PA
    Posts
    22

    Is there an off-by-one error in this example code?

    Right, so in a K&R exercise, I'm supposed to modify this code (which I haven't touched yet). It currently uses the getline() function to read in lines from input, find the longest one, and output it up to 1000 chars.

    I am supposed to change the getline() function to calculate and display the true length of the longest line, but only save 1000 chars (including \n and \0) to an array
    and display those. Anything beyond the 1000th character is not displayed.

    Here is the code I am to be working with:

    Code:
    /* Corresponding K&R Section: 1-9 */
    
    /* Revise longest-line program to print length of
     	arbitrarily long lines and show as much as
    	possible of the longest line */
    
    #include <stdio.h>
    
    #define MAXLINE 1000 /* maximum input line length */
    
    int getline(char line[], int maxline);
    void copy(char to[], char from[]);
    
    /* print the longest input line */
    int main(void)
    {
    	int len = 0;					/* current line length */
    	int max = 0;					/* maximum length seen so far */
    	char line[MAXLINE] = {0};		/* current input line */
    	char longest[MAXLINE] = {0};	/* longest line saved here */
    	
    	while ((len = getline(line, MAXLINE)) > 0)
    		if (len > max)
    		{
    			max = len;
    			copy(longest, line);
    		}	
    	if (max > 0) /* there was a line */
    		printf("%s", longest);
    	return 0;
    }
    
    /* getline: read a line into s, return length */
    int getline(char s[], int lim)
    {
    	int i = 0; c = 0;
    	
    	for (i = 0; i < lim - 1 && (c=getchar()) != EOF && c != '\n'; ++i)
    		s[i] = c;
    	if (c == '\n')
    	{
    		s[i] = c;
    		++i;
    	}
    
    	s[i] = '\0';
    	
    	return i;
    }
    
    /* copy: copy 'from' into 'to'; assume to is big enough */
    void copy(char to[], char from[])
    {
    	int i;
    
    	i = 0;
    	while ((to[i] = from[i]) != '\0')
    		++i;
    }
    My confusion stems primarily from this part in getline():

    Code:
    for (i = 0; i < lim - 1 && (c=getchar()) != EOF && c != '\n'; ++i)
    	s[i] = c;
    if (c == '\n')
    {
    	s[i] = c;
    	++i;
    }
    
    s[i] = '\0';
    The limit being passed to that function is 1000, the same as the size of the array being passed. The for loop is incrementing i from 0 to 999 (lim - 1). Let's assume that I have an input line 2000 chars in length, and I get to character 998. This is put into the array with "s[i] = c". Fine, now I'm going to break out of the loop because i = lim - 1 = 999.

    But now that I've broken out, it seems like it could write '\n' at index 999 then write the null-terminator off the end of the array at index 1000, which is out of bounds. Am I wrong here? Does it work differently because the unary operator in the increment part of the for loop is prefixed?
    Evan Williams
    Lehigh University Senior
    Computer Science and Engineering

  2. #2
    Registered User
    Join Date
    May 2009
    Posts
    2,608
    With lim equal to 1000 the max valid value in for loop is 998 because 999 is not less that (1000-1).
    Code:
    i < lim - 1
    Tim S.

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Your for loop will not be able to die with both i equal to 999 and c equal to '\n' -- for if character 998 was '\n', the loop would stop early (while i was still 998) and if the loop stops with i equal to 999, no new character is read into c because of the short-circuit (so even if character 999 was '\n' c would not contain it).

  4. #4
    Registered User edw211's Avatar
    Join Date
    Jun 2011
    Location
    Wilkes-Barre, PA
    Posts
    22
    Quote Originally Posted by tabstop View Post
    Your for loop will not be able to die with both i equal to 999 and c equal to '\n' -- for if character 998 was '\n', the loop would stop early (while i was still 998) and if the loop stops with i equal to 999, no new character is read into c because of the short-circuit (so even if character 999 was '\n' c would not contain it).
    Ohhhhh, it all makes sense now then. Okay, thanks. I had forgotten about short-circuiting. I was thinking as though everything in the loop condition was carried out with every test.
    Evan Williams
    Lehigh University Senior
    Computer Science and Engineering

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with code, I can't seem to fix the error
    By saszew in forum C Programming
    Replies: 2
    Last Post: 11-13-2008, 07:28 PM
  2. error in my code, please help
    By Leeman_s in forum C++ Programming
    Replies: 4
    Last Post: 05-25-2003, 04:10 PM
  3. error with code
    By duffy in forum C Programming
    Replies: 8
    Last Post: 10-22-2002, 09:45 PM
  4. i have an error in this code help?
    By ssjnamek in forum C++ Programming
    Replies: 12
    Last Post: 01-26-2002, 09:48 PM
  5. error in code
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 11-25-2001, 06:39 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21