K& R答案书 - 练习1.16 - getline功能

时间:2013-12-28 17:08:53

标签: c

“修改最长行程序的主程序,以便正确打印任意长输入行的长度,并尽可能多地打印文本。”

以下是练习1.16的K& R答案书中的完整代码:

#include <stdio.h>
#define MAXLINE 1000

int getline (char line[], int maxline);
void copy (char to[], char from[]);
main()
{


int len;
int max; 
char line[MAXLINE];
char longest[MAXLINE];

max = 0;
while ((len = getline(line, MAXLINE)) > 0 ){
    printf("%d %s", len, line);
    if (len >max){
        max = len;
        copy (longest, line);
    }
}
if (max > 0)
    printf("%s", longest);

getchar();
return 0;
}
int getline(char s[], int lim)
{
int c, i, j;

j = 0;
for (i = 0; (c = getchar()) != EOF && c != '\n'; ++i)
    if (i < lim-2){
        s[j] = c;
        ++j;
    }
    if (c == '\n'){
        s[j] = c;
        ++j;
        ++i;
    }
    s[j] = '\0';
    return i;
}
void copy (char to[], char from[])
{
int i;

i = 0;
while ((to[i] = from[i]) != '\0')
    ++i;
}

查看getline函数,在以下行中使用lim-2而不是lim-1的目的是什么:

if (i < lim-2){

这似乎没有任何用处。不应该在s [lim]而不是s [lim-1]或s [lim-2]处出现'\ 0'字符标记吗?

此外,该函数会跳过最新字符,如果超过字符限制,直到找到一个新行字符,并将换行符添加到char字符串,但跳过下一个“fittable”字符来自流程中的输入流。这个目的是什么?

我不确定作者在这里打算做什么,这本书没有提供任何解释。

编辑:使用像行[5]这样的数组,我的印象是字符数组中的NULL字符在行[5]中,我们可以在数组下标0-4中放置一些东西。这个假设是假的吗?

2 个答案:

答案 0 :(得分:1)

  

这似乎没有任何用处。不应该'\ 0'   字符标记出现在s [lim]而不是s [lim-1]或s [lim-2]?

没有。 lim是缓冲区的大小,因此数组的最后一个索引是lim-1。 代码使用lim-2因为它保留了结束字符串字符('\ 0')和新行(“\ n”)的空间。

  

此外,该功能会跳过最新的角色,如果有的话   超过字符限制,直到找到一个新的行字符,然后它   将换行符添加到char字符串,但跳过任何内容   来自输入流的下一个“fittable”字符。   这个目的是什么?

getline函数读取分成不同大小MAX_LINE的块的输入字符串,然后将这些块复制到longest缓冲区中。由于longest缓冲区具有固定大小,因此可以打印的字符串的最大长度是MAX_LINE(即仅第一个块)。因此,即使在输入中插入较长的字符串,longest缓冲区的大小也是可以打印出来的字符串的实际限制。练习包括使longest缓冲区动态化,以便应用程序能够读取和打印任意长字符串。您必须使用动态内存,因为您不知道输入字符串的大小。一种可能的解决方案是将每个块保存到临时缓冲区中,当所有缓冲区都在内存中时,您可以计算输入字符串的大小,然后将所有块复制到一个新的缓冲区中,该缓冲区的大小是输入字符串的长度。

答案 1 :(得分:0)

是的,我刚刚读了同一页并且也很困惑。在以下情况下,我认为这只是错误的:

1。输入行超过lim;

2。输入行直接以EOF结束,没有换行符\n

这样它只会将有意义的字符保存到s[lim-3],将\0放入s[lim-2]并使s[lim-1]不使用。

然而在实践中(我使用OSx),EOF只能通过在行的开头键入control-D来触发 - 这意味着所有行都以\n结尾(特别是最后一行)线)。因此,无论它是否超过lim,最后s[]中保存的最后两个字符始终为\n\0

当输入是文件的一个主干而不是终端上的输入时,你可以阅读这个:Why should text files end with a newline?我今天也发现了这个问题,我认为这两个问题是高度相关的。

希望我的回答有所帮助! :)