这对我来说看起来像是一个小虫,但是我很困惑,考虑到这本书的年龄和受欢迎程度,我的观察结果似乎没有出现在互联网上的任何其他地方。或者也许我只是擅长搜索,或者根本不是一个错误。
我正在谈论第一章中“打印出最长的输入线”程序。这是代码:
#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 */
main()
{
int len; /* current line length */
int max; /* maximum length seen so far */
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here */
max = 0;
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 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;
}
/* 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;
}
现在,在我看来,它应该是lim-2
而不是getline条件中的lim-1
。否则,当输入完全是最大长度,即999个字符后跟'\n'
时,getline将索引到s[MAXLINE]
,这是超出范围的,并且复制时也可能发生各种可怕的事情被调用,from[]
不以'\0'
结尾。
答案 0 :(得分:8)
我觉得你在某个地方感到困惑。这个循环条件:
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
确保i
永远不会大于lim - 2
,因此在最大长度的情况下,i
在循环退出并且存储空字符后为lim-1
最后一个位置。
答案 1 :(得分:2)
如果是999个非\ n字符后跟\ n,则c永远不等于\ n。当for循环退出时,c等于最后一个非换行符。
所以c!='\ n'并且不会进入i ++的块,所以我永远不会超出范围。
答案 2 :(得分:1)
如果输入的长度为999
且后跟\n
,则限制值为1000
,lim -1
的值将变为999
,当i < lim -1
变为i
时,循环测试条件998
将变为false。对于i < 999
,c == \n
永远不会为真,因此数组s
将编入索引s[999]
而非s[1000]