首页 文章

C-可以fgets接受NULL参数吗?

提问于
浏览
2

我意识到C语言中有一些函数有可选参数,这意味着用户可以传递NULL作为参数值 . 我很好奇是否可以使用fgets() .

假设我想将整行作为字符串保存在文件中,换句话说,我希望fgets()在到达换行符(\ n)时停止,然后我可以执行以下操作吗?

fgets(string, NULL, file);  //where string is simply an array of char

我认为这是可能的,因为fgets()总是在到达换行符时停止,但如果不可能,当一个人不知道行长时,将整行保存为字符串的正确程序是什么?

3 回答

  • 3

    C实际上没有可选参数 .
    虽然有些函数为某些参数定义了特殊值(最常见的是指针参数的空指针),这意味着"do the default" .

    您可以通过 INT_MAX 使用fgets,如gets作为特定文件,从而有效地删除限制 .
    在考虑这样做之前,请考虑一下为什么C禁止 gets 从标准库中删除 .

    另外, NULL 是一个实现定义的空指针常量,这可能意味着它不能隐式转换为 int .

  • 3

    NULL 作为size参数传递给 fgets 基本上传递 0 . NULL通常定义为

    #define NULL 0
    

    但它意味着用作指针,而不是int .

    我怀疑fgets()在传递 0 大小时的行为要么是未定义的,要么是无操作 .

    文档(在linux上)说明

    fgets() reads in at most one less than size characters from  stream  and  stores  them
    into  the  buffer pointed  to  by s.  Reading stops after an EOF or a newline.  If a
    newline is read, it is stored into the buffer.  A terminating null byte ('\0') is stored
    after the last character in the buffer.
    

    它是如何读取 -1 个字符的?它会在哪里存储尾随 NUL

    这就是为什么我倾向于未定义的行为 .

    在不知道它们可能有多长时间的字符串读取方面,有两个部分要处理:

    • 首先,使静态缓冲区大于最长的预期行,以最大限度地减少失败的可能性 .

    • 处理 fgets 返回一个完整的缓冲区(其中 s[size-2] != '\n' ),通过一个动态分配的缓冲区,你通过 realloc 增长,并用来连接 fgets 的连续返回,直到它看到一个新的行 .

  • 3

    请改用 getline 功能 . 这是手册页中的示例代码

    char *line = NULL;
           size_t linecap = 0;
           ssize_t linelen;
           while ((linelen = getline(&line, &linecap, fp)) > 0)
                   fwrite(line, linelen, 1, stdout);
    

    注意 getline 将自动 realloc 缓冲区,如果's not big enough, and it'你不再需要 free 缓冲区 .

相关问题