我正在使用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。
答案 0 :(得分:5)
重要的是不要强制fgetc()
返回char
。 fgetc()
(和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,不需要说明。a[x]
代替*(a+x)
),它更具可读性。 编辑:添加了分配检查。使用了苛刻的方法。在那种情况下我们还能做些什么?
答案 1 :(得分:1)
您没有标记字符串的结尾。
return_str[chars_read] = '\0';
return return_str;