C fgets读取行

时间:2014-12-10 16:02:53

标签: c caching stdin fgets

拜托,你能帮助我,如何通过fgets从stdin读取行?问题是,有时在tmp_string中存储来自两行之前的数据的一部分等等...我使用此代码加载行:

int loadLine(Line *line) {
    char tmp_string[MAX_LOAD];
    int return_val;
    return_val = 0;
    line->length = MAX_LOAD;
    line->index = 0;
    line->data = (char*) malloc(sizeof (char) * line->length);

    while (fgets(tmp_string, MAX_LOAD - 1, stdin) != NULL) {
        strncat(line->data, tmp_string, MAX_LOAD);
        line->index += strlen(tmp_string);
        if (tmp_string[strlen(tmp_string) - 1] == '\n') { /* if I'm at the end of line... */
            line->data[strlen(line->data) - 1] = '\0';
            return_val = 1;
            break;
        }
        if ((line->index + MAX_LOAD) > line->length) {
            resizeLine(line);
        }

    }

    if(feof(stdin))
    {
        return_val = 0;
    }

    return return_val;
}

这是用法:

Line line;
if(loadLine(&line) == 0){ ... }
free(line.data);

2 个答案:

答案 0 :(得分:1)

line->data尚未初始化(没有终止符),因此strncat()可能会失败。

line->data = malloc(sizeof (char) * line->length);
line->data[0] = 0;

答案 1 :(得分:0)

回答你提出的问题,虽然你浪费了fgets()变量的一个字节,但你对tmp_string的使用看起来很合理。 fgets()函数已经知道为尾随NUL保留一个字节,所以如果你正在读取一个长度为MAX_LOAD的数组,那么你通常会使用

fgets(tmp_string, MAX_LOAD, stdin);

这将覆盖目标缓冲区(tmp_string)的先前内容,直到读取的字节数加上1,并且它将在读取最后一个字节后自动添加字符串终止符。如果先前读取的行更长,则其尾部可能保留在缓冲区中,但这不重要,因为标准字符串函数将忽略终结符之后的任何内容。

您看到的不当行为很可能是由于您未能将line->data初始化为零长度字符串,然后再将其传递给strncat(),而正如Weather Vane首先观察到的那样。