首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >K&R答案手册-练习1.16 - getline函数

K&R答案手册-练习1.16 - getline函数
EN

Stack Overflow用户
提问于 2013-12-29 01:08:53
回答 2查看 952关注 0票数 2

修改最长行程序的main例程,使其能够正确打印任意长度的输入行,并尽可能多地打印文本。

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

代码语言:javascript
复制
#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的目的是什么:

代码语言:javascript
复制
if (i < lim-2){

这似乎没有任何用处。'\0‘字符标记不应该出现在slim,而不是slim-1或slim-2

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

我真的不确定作者在这里的意图,这本书也没有提供任何解释。

编辑:使用像line5这样的数组,我的印象是字符数组中的空字符放在line5中,我们可以将一些东西放在数组的下标0-4中。这个假设是错误的吗?

EN

回答 2

Stack Overflow用户

发布于 2013-12-29 01:23:40

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

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

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

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

票数 1
EN

Stack Overflow用户

发布于 2017-01-08 23:23:18

是的,我只是碰巧读到了同样的页面,也感到困惑。我认为只有在以下情况下才是错误的:

1.输入行超过lim

2.输入行直接以EOF结尾,不带换行符\n

因此,它只将有意义的字符保存到s[lim-3],将\0放在s[lim-2]中,而不使用s[lim-1]

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

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20817144

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档