fgets 有更好的替代品吗?

Cla*_*ese 1 c string fgets

我只是一名年轻的计算机科学学生,目前我对从stdin读取字符串的最佳实践有点困惑。我知道有很多方法可以做到这一点,有些方法比其他方法更安全,等等...我目前需要一个函数来防止缓冲区溢出并在末尾附加一个空终止符(\0)字符串的。我发现fgets对此非常有用,但是......它会停止读取 \n 或 EOF!如果我希望用户一次输入多行怎么办?还有其他功能可以帮助我做到这一点吗?如果这个问题对你们中的一些人来说似乎很愚蠢,我很抱歉,但是请理解我!任何帮助,将不胜感激。

Edw*_*rak 5

#define INITALLOC  16  /* #chars initally alloced */
#define STEP        8  /* #chars to realloc by */

#define END       (-1)  /* returned by getline to indicate EOF */
#define ALLOCFAIL    0  /* returned by getline to indicate allocation failure */
int getline(char **dynline)
{
    int i, c;
    size_t nalloced;  /* #chars currently alloced */

    if ((*dynline = malloc(INITALLOC)) == NULL)
        return ALLOCFAIL;

    nalloced = INITALLOC;
    for (i = 0; (c = getchar()) != EOF; ++i) {
        /* buffer is full, request more memory */
        if (i == nalloced)
            if ((*dynline = realloc(*dynline, nalloced += STEP)) == NULL)
                return ALLOCFAIL;

        /* store the newly read character */
        (*dynline)[i] = c;
    }
    /* zero terminate the string */
    (*dynline)[i] = '\0';

    if (c == EOF)
        return END;
    return i+1;  /* on success, return #chars read successfully 
                    (i is an index, so add 1 to make it a count */
}
Run Code Online (Sandbox Code Playgroud)

该函数动态分配内存,因此调用者需要free内存。

这段代码并不完美。如果在重新分配时出现故障,则会NULL覆盖以前完美的数据,从而导致内存泄漏和数据丢失。

  • 太糟糕了,你使用了“getline”名称,它在 POSIX 上有不同的含义 (2认同)
  • 你正在浪费返回值;您应该使用它来指示读取了多少个字符。分配失败时发生内存泄漏;你刚刚用空指针覆盖了`*dynline`;遗憾的是没有其他方法可以释放以前分配的内容。研究POSIX的设计[`getline()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html); 它有很多优点。 (2认同)