fgetc返回一个奇怪的角色

时间:2015-03-01 08:08:40

标签: c char

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

这是我的代码实现:

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\n\337

我真的很好奇这意味着什么。我在网上看了,但没有提到它。它可能是特定于平台的吗?

我正在运行以下版本的gcc:

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

我正在运行openSuse。

2 个答案:

答案 0 :(得分:5)

重要的是不要强制fgetc()返回charfgetc()(和fgets())完全返回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;
}

我改变了其他一些小问题。

  • realloc() NULL作为第一个参数与malloc()相同,因此通过重新排列循环中的(重新)分配可以避免不必要的代码。
  • sizeof (char)根据定义1,不需要说明。
  • EOF值(即-1)不会进入循环,也不会与字符0xFF混淆。
  • 如果已达到EOF,则该函数返回NULL。这是一个功能性的选择,可以有用(或不)。这取决于具体情况。
  • 使用数组语法(a[x]代替*(a+x)),它更具可读性。

编辑:添加了分配检查。使用了苛刻的方法。在那种情况下我们还能做些什么?

答案 1 :(得分:1)

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

return_str[chars_read] = '\0';
return return_str;