microbit
microbit

Reputation: 349

Is there an error in the example code in chapter 1.9 in the classic book "The C Programming Language"?

In the Chapter 1.9 in the classic book about C language "The C Programming Language" by Brian & Dennis, there is a bunk of code about a function 'getline' which is used to copy the next line of input text into a char type string and check the overflow. I quote the code below:

int getline(char line[], int maxline);
int getline(char s[], int limit)
{
    int c,i;
    for (i=0; i<limit-1 && (c=getchar())!=EOF && c!='\n'; ++i) /* ** */
        s[i]=c;
    if (c == '\n') {
        s[i]=c;
        ++i;
    }
    s[i] = '\0';
    return i;
}

Here is the problem: the parameter 'limit' is the max length of the line, so the array s[] can only contain a collection of elements from s[0] to s[limit-1]. If the last character for the variable c to getchar() is '\n' and this character's index is limit-1, then the judgement part in the 'for' loop will fail because of 'i==limit-1' but not 'c!='\n' (according to the sequence from left to right). Next, if clause will work, because of 'c=='\n'', then s[limit-1]=c, then ++i will set the value of i into limit. s[i]='\0' will overflow, because s[limit] overrun the limit of string. Is my analysis right or not? Thanks for any helpful answers.

Upvotes: 4

Views: 349

Answers (2)

WhozCraig
WhozCraig

Reputation: 66224

There are two short circuited eval-points points in this code. See below

for (i=0; i<limit-1 && (c=getchar())!=EOF && c!='\n'; ++i)
//        (   A   )    (        B        )   (  C  )

All are separated with a chain of &&. When this code executes, all three must be true or the loop will break. But with short circuit eval the following happens:

  • If A is false, the condition is false, neither B nor C are evaluated.
  • Else if B is false, the condition is false and C is not evaluated.
  • Else if C is false, the condition is false.

Therefore...

  • if i<limit-1 is false, neither the getchar() and comparison against EOF, nor the comparison against '\n' are performed.
  • else if (c=getchar())!=EOF is false, then the comparison against '\n' is not performed.
  • else the comparison against '\n' is performed.

i hope that made sense.

Upvotes: 3

Filipe Gon&#231;alves
Filipe Gon&#231;alves

Reputation: 21213

Your analysis is wrong. If i == limit-1, the loop breaks without reading into c, due to short-circuit evaluation. So, you never enter if (c == '\n'). i remains limit-1 and there is no overflow.

Conceptually, you can think of the loop condition like this: "If i is lower than limit-1, read a character, and if it's not EOF or newline, enter the loop body." Thus, if i is limit-1, you never read.

Upvotes: 4

Related Questions