Here is a sample from Kernighan & Ritchie's "The C Programming Language":
以下是Kernighan&Ritchie的“The C Programming Language”的示例:
int getline(char s[], int lim)
{
int c, i = 0;
while (--lim > 0; && (c=getchar()) !=EOF && c !='\n')
{
s[i++] = c;
}
if (c =='\n')
{
s[i++] = c;
}
s[i] = '\0';
return i;
}
Why do we should check if c != '\n'
, despite we use s[i++] = c
after that?
为什么我们应该检查c!='\ n',尽管我们之后使用s [i ++] = c?
8 个解决方案
#1
3
The functions reads characters from the standard input until either EOF or a newline characters is found.
这些函数从标准输入中读取字符,直到找到EOF或换行符。
The second check ensures that the only newline character is put into the char array. EOF shouldn't occur in a proper c-string. Also, if the character isn't newline that means that we might have filled up our c-string, in which case we shouldn't put any more characters into it.
第二次检查确保将唯一的换行符放入char数组中。 EOF不应出现在正确的c弦中。此外,如果字符不是换行符,则意味着我们可能已经填充了我们的c字符串,在这种情况下,我们不应该再添加任何字符。
Notice we still append the '\0'. We've ensured that theres still room for one more character in our c-string, as we use the pre-fix decrementor, which evaluates before the comparison.
请注意,我们仍然附加'\ 0'。我们已经确保在我们的c字符串中还有一个字符可用空间,因为我们使用预定义递减器,它在比较之前进行评估。
#2
1
The comparison is to ensure readline terminates when it encounters a newline character (the '\n'). On the iteration where it does, it terminates without adding the newline to the string, so the statement after that ensures that the string is always newline terminated, even if one of the other termination conditions was reached.
比较是为了确保readline在遇到换行符('\ n')时终止。在它执行的迭代中,它终止而不向字符串添加换行符,因此之后的语句确保字符串始终以换行符终止,即使已达到其他终止条件之一。
#3
1
There is a bug in the code.
代码中有一个错误。
If the size of s is N bytes and the user types a newline as the (N-1)th character, the Nth character will become a '\n' and the (N+1)th character (which is not allocated) will become a '\0'.
如果s的大小是N个字节并且用户键入换行符作为第(N-1)个字符,则第N个字符将变为'\ n'并且第(N + 1)个字符(未分配)将成为'\ 0'。
#4
0
You do that just to exit the while loop on new line. Else you would have to check it in while body and use break.
你这样做只是为了在新行上退出while循环。否则你必须在身体和使用休息时检查它。
#5
0
That ensures that you stop at the end of the line even if it's not the end of the input. Then if there is a newline the \n is added to the end of the line and i incremented one more time to avoid overwriting it with the \0.
即使它不是输入的结尾,这也可以确保您在行尾停止。然后,如果有换行符,则将\ n添加到行的末尾,然后再增加一次,以避免使用\ 0覆盖它。
#6
0
int getline(char s[], int lim)
{
int c, i;
i=0;
/* While staying withing limit and there is a char in stdin and it's not new line sign */
while (--lim > 0; && (c=getchar()) !=EOF && c !='\n')
/* Store char at the current position in array, advance current pos by one */
s[i++] = c;
/* If While loop stopped on new-line, store it in array, advance current pos by one */
if (c =='\n')
s[i++] = c;
/* finally terminate string with \0 */
s[i] = '\0';
return i;
}
#7
0
I'm not sure whether I understand the question. c !='\n'
is used to stop reading the line when the end of line (linefeed) occurs. Otherwise we would always read it until the limit even if it ends before. The first s[i++] = c;
in the while-loop doesn't occur if a linefeed has been reached. That's why there is the special test afterwards and the other s[i++] = c;
in case it was a linefeed which broke the loop.
我不确定我是否理解这个问题。 c!='\ n'用于在行结束(换行)时停止读取行。否则,即使它在之前结束,我们也会一直读到它。第一个s [i ++] = c;如果已到达换行符,则不会发生while循环。这就是为什么之后有特殊的测试而另一个s [i ++] = c;如果它是一个打破循环的换行。
#8
0
Not answering your question, but I'll write some comments anyway:
没有回答你的问题,但我还是会写一些评论:
I don't remember all K&R rules, but the function you've listed will fail if lim is equal to one. Then you won't run the loop which leaves c unintialised, but you'll still use the variable in the if (c == '\n') check.
我不记得所有的K&R规则,但是如果lim等于1,你列出的函数将会失败。然后你不会运行离开c unintialised的循环,但你仍然会在if(c =='\ n')检查中使用该变量。
Also the while (--lm > 0; ...) thing will not go through the compiler. Remove the ';' and it does.
while(--lm> 0; ...)的东西也不会通过编译器。除掉 ';'它确实如此。
#1
3
The functions reads characters from the standard input until either EOF or a newline characters is found.
这些函数从标准输入中读取字符,直到找到EOF或换行符。
The second check ensures that the only newline character is put into the char array. EOF shouldn't occur in a proper c-string. Also, if the character isn't newline that means that we might have filled up our c-string, in which case we shouldn't put any more characters into it.
第二次检查确保将唯一的换行符放入char数组中。 EOF不应出现在正确的c弦中。此外,如果字符不是换行符,则意味着我们可能已经填充了我们的c字符串,在这种情况下,我们不应该再添加任何字符。
Notice we still append the '\0'. We've ensured that theres still room for one more character in our c-string, as we use the pre-fix decrementor, which evaluates before the comparison.
请注意,我们仍然附加'\ 0'。我们已经确保在我们的c字符串中还有一个字符可用空间,因为我们使用预定义递减器,它在比较之前进行评估。
#2
1
The comparison is to ensure readline terminates when it encounters a newline character (the '\n'). On the iteration where it does, it terminates without adding the newline to the string, so the statement after that ensures that the string is always newline terminated, even if one of the other termination conditions was reached.
比较是为了确保readline在遇到换行符('\ n')时终止。在它执行的迭代中,它终止而不向字符串添加换行符,因此之后的语句确保字符串始终以换行符终止,即使已达到其他终止条件之一。
#3
1
There is a bug in the code.
代码中有一个错误。
If the size of s is N bytes and the user types a newline as the (N-1)th character, the Nth character will become a '\n' and the (N+1)th character (which is not allocated) will become a '\0'.
如果s的大小是N个字节并且用户键入换行符作为第(N-1)个字符,则第N个字符将变为'\ n'并且第(N + 1)个字符(未分配)将成为'\ 0'。
#4
0
You do that just to exit the while loop on new line. Else you would have to check it in while body and use break.
你这样做只是为了在新行上退出while循环。否则你必须在身体和使用休息时检查它。
#5
0
That ensures that you stop at the end of the line even if it's not the end of the input. Then if there is a newline the \n is added to the end of the line and i incremented one more time to avoid overwriting it with the \0.
即使它不是输入的结尾,这也可以确保您在行尾停止。然后,如果有换行符,则将\ n添加到行的末尾,然后再增加一次,以避免使用\ 0覆盖它。
#6
0
int getline(char s[], int lim)
{
int c, i;
i=0;
/* While staying withing limit and there is a char in stdin and it's not new line sign */
while (--lim > 0; && (c=getchar()) !=EOF && c !='\n')
/* Store char at the current position in array, advance current pos by one */
s[i++] = c;
/* If While loop stopped on new-line, store it in array, advance current pos by one */
if (c =='\n')
s[i++] = c;
/* finally terminate string with \0 */
s[i] = '\0';
return i;
}
#7
0
I'm not sure whether I understand the question. c !='\n'
is used to stop reading the line when the end of line (linefeed) occurs. Otherwise we would always read it until the limit even if it ends before. The first s[i++] = c;
in the while-loop doesn't occur if a linefeed has been reached. That's why there is the special test afterwards and the other s[i++] = c;
in case it was a linefeed which broke the loop.
我不确定我是否理解这个问题。 c!='\ n'用于在行结束(换行)时停止读取行。否则,即使它在之前结束,我们也会一直读到它。第一个s [i ++] = c;如果已到达换行符,则不会发生while循环。这就是为什么之后有特殊的测试而另一个s [i ++] = c;如果它是一个打破循环的换行。
#8
0
Not answering your question, but I'll write some comments anyway:
没有回答你的问题,但我还是会写一些评论:
I don't remember all K&R rules, but the function you've listed will fail if lim is equal to one. Then you won't run the loop which leaves c unintialised, but you'll still use the variable in the if (c == '\n') check.
我不记得所有的K&R规则,但是如果lim等于1,你列出的函数将会失败。然后你不会运行离开c unintialised的循环,但你仍然会在if(c =='\ n')检查中使用该变量。
Also the while (--lm > 0; ...) thing will not go through the compiler. Remove the ';' and it does.
while(--lm> 0; ...)的东西也不会通过编译器。除掉 ';'它确实如此。