fgetc returns 一个奇怪的字符

fgetc returns a strange character

我正在使用 fgetc() 读取输入直到 EOF。我 运行 遇到了一个奇怪的问题。在 EOF 之前,我得到一个字符 7。我不确定那是什么。

这是我的代码实现:

char *get_file_paths() 
{
        char *return_str = NULL;
        int chars_read = 0;
        size_t buf_sz = 80;

        return_str = (char *) malloc(buf_sz * sizeof(char));

        while((*(return_str + chars_read) = fgetc(stdin)) != EOF) {
                chars_read++;
                if ((chars_read + 1) == buf_sz) {
                        buf_sz *= 2;
                        return_str = realloc(return_str, buf_sz);
                }
        }

        return return_str;

}

例如,如果我有一个字符串:assignment_2/grepout.txt。在 gdb 中查看 return_str 时,我得到以下信息:

assignment_2/grepout.txt\n7

我很好奇这是什么意思。我在网上查了一下,但没有提到它。它可以是特定于平台的吗?

我是运行以下版本的gcc:

gcc version 4.8.1 20130909 [gcc-4_8-branch revision 202388] (SUSE Linux)

我是 运行 openSuse。

你没有标记字符串的结尾。

return_str[chars_read] = '[=10=]';
return return_str;

重要的是不要将 fgetc() 的 return 强制键入 charfgetc()(和 fgets())return int 而不是 char 正是因为 EOF 是一个超出字符范围的值。您的 0337(0xFF 或十进制的 255)在大多数实现中都是有效字符(它是代码页 1252、ISO-8859-15 和 Unicode 中的字符 ÿ)。 在你的循环中,如果你在键盘上输入那个字符,你将有与 EOF 相同的行为。

因此您应该将循环更改为:

char *get_file_paths(void) 
{  
    int chars_read = 0;
    size_t buf_sz = 0;
    int ch;
    char *return_str = NULL;

    while((ch = fgetc(stdin)) != EOF) {
        if(chars_read == buf_sz) {
            buf_sz += 80;
            void *no_leak = realloc(return_str, buf_sz+1);
            if(!no_leak) {
              perror("No memory\n");
              abort();
            }
            return_str = no_leak;
         }
         return_string[chars_read++] = ch;
    }
    if(return_string)
        return_string[chars_read++] = 0;
    return return_str;
}

我换了其他几个小的"issues"。

  • realloc()NULL 作为第一个参数与 malloc() 相同,因此通过在循环中重新安排(重新)分配,您可以避免不必要的代码。
  • sizeof (char)定义为1,无需说明。
  • EOF 值(即 -1)未进入循环且未与字符 0xFF 混淆。
  • 如果已经到达 EOF,函数 returns NULL。这是一个可能有用(或无用)的功能性选择。这取决于上下文。
  • 使用数组语法(a[x] 而不是 *(a+x)),它的可读性要高得多。

编辑:添加了分配检查。用了狠辣的手段。在那种情况下我们还能做什么?