Reputation: 158
I am currently studying the well-known book for C - The C Programming Language, 2Ed. And when I trying the code in P.29, I think there is something wrong in the getline function:
int getline(char s[], int lim) {
int c, i;
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;
}
What if when the for loop ended, i == lim-1
and c == '\n'
? In this case, I think the array would be out of boundary, since s[lim]
would be set to '\0'.
Does anyone think this is wrong? Thanks for your help.
Upvotes: 5
Views: 168
Reputation: 64308
It isn't possible for i
to be lim-1
and c
to be '\n'
at the same time. If i==lim-1
, then i<lim-1
will be false, so it will never read the next character. If c
was '\n'
, then the loop would have terminated before i
got to be lim-1
.
The loop is equivalent to this:
i=0;
while (i<lim-1) {
c = getchar();
if (c==EOF) break;
if (c=='\n') break;
s[i] = c;
i++;
}
Upvotes: 0
Reputation: 81936
So, let's look at some cases:
If lim == 0
:, then this will do undefined behavior. There's two places this will happen:
i == 0
and c == undefined
.c
at (c == '\n')
. It has no defined value yet, so it's undefined behavior.s
with: s[i] = '\0';
What if lim == 1
:
lim == 0
because c
has no value.What if lim == 2
, and the input string is "ab"
:
'a'
, and place it into s
.c
still being 'a'
.s == "a\0"
What if lim == 2
and the input string is "a\n"
(Which is the case you're worried about):
'a'
, and place it into s
.c
still being 'a'
.s == "a\0"
Upvotes: 2
Reputation: 153517
I think you are correct. - but in a different way.
There may have been is a problem. Should the limit be reached i==lim-1
, and c had the value \n
from the previous loop - but this can not happen as the previous loop c!='\n'
would have exited.
This is a problem with lim <=1
. The for loop exits, and c
is not intiialized yet, thus undefined behavior with if (c == '\n')
. Could be fixed with
int c = 0;
As mentioned by others, there is an additional problem with lim = 0
and s[i] = '\0';
Upvotes: 0
Reputation: 106022
Loop will continue until the condition i < lim-1
is true.When i == lim - 1
, condition for loop becomes false and loop will terminate, and last element of array will stored in s[lim -2]
.It will not go out of boundary.
Upvotes: 0
Reputation: 239051
The &&
operator has "early-out" semantics. This means that if i == lim-1
, the rest of the condition is not executed - in particular, c = getchar()
will not be called.
This means that in this case, c
will have its value from the last iteration of the loop - and since the loop condition includes c != '\n'
, this value can't be '\n'
(or the loop would have exited last time around).
This is true as long as lim
is greater than 1, which must be a precondition of the function (because calling the function with lim
less than or equal to 1 would cause the uninitialised value of c
to be read).
Upvotes: 4