2

这对我来说看起来像是一个错误,但是我很困惑,考虑到这本书的年代和受欢迎程度,我的观察似乎没有出现在互联网上的其他任何地方。或者也许我只是不擅长搜索,或者它根本不是一个错误。

我说的是第一章中的“打印出最长的输入行”程序。这是代码:

#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;
} 

现在,在我看来,它应该与 getline 的 for 条件lim-2相反lim-1。否则,当输入恰好是最大长度时,即 999 个字符后跟'\n',getline 将索引到,这是超出范围的,并且当调用 copy 并且不以 a 结尾s[MAXLINE]时,可能会发生各种可怕的事情。from[]'\0'

4

3 回答 3

8

我想你在某个地方感到困惑。这个循环条件:

for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)

确保i永远不会大于lim - 2,因此在最大长度的情况下,ilim-1在循环退出并且空字符存储到最后一个位置之后。

于 2013-08-20T17:32:17.230 回答
2

在 999 个非 \n 字符后跟 \n 的情况下,c 永远不会等于 \n。当 for 循环退出时, c 等于最后一个非换行符。

所以 c != '\n' 并且不会进入执行 i++ 的块,因此 i 永远不会越界。

于 2013-08-20T17:46:32.397 回答
1

当输入为length999且后跟时\n,limit 的值是1000,而 的值lim -1将变为,当变为时999,循环测试条件i < lim -1为假。对于,永远不会是真的,因此数组将被索引到而不是i998i < 999c == \nss[999]s[1000]

于 2013-08-20T17:49:09.487 回答