在 Brian & Dennis 所著的关于 C 语言的经典书籍“C 编程语言”的第 1.9 章中,有一段关于函数“getline”的代码,该函数用于将输入文本的下一行复制到字符类型字符串中并检查溢出。我引用下面的代码:
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;
}
问题来了:参数“limit”是行的最大长度,所以数组 s[] 只能包含从 s[0] 到 s[limit-1] 的元素集合。如果变量c到getchar()的最后一个字符是'\n',并且这个字符的索引是limit-1,那么'for'循环中的判断部分会因为'i==limit-1'而失败,但不是'c!='\n'(按照从左到右的顺序)。接下来,if 子句会起作用,因为'c=='\n'',那么s[limit-1]=c,那么++i 会将i 的值设置为limit。 s[i]='\0' 会溢出,因为 s[limit] 超出了字符串的限制。我的分析对还是不对?感谢您提供任何有用的答案。
最佳答案
你的分析是错误的。如果 i == limit-1
,由于短路评估,循环中断而不读入 c
。所以,你永远不要输入 if (c == '\n')
。 i
仍然是 limit-1
并且没有溢出。
从概念上讲,您可以这样考虑循环条件:“如果 i
低于 limit-1
,则读取一个字符,如果不是 EOF 或换行符,则进入循环体。”因此,如果 i
是 limit-1
,则您永远不会阅读。
关于c - 经典书籍 "The C Programming Language"1.9 章示例代码有错误吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25209442/