我有一个问题,我在一个循环中构造一个字符串,该字符串输出到stout显示字符串和一个字符'y',上面有两个点作为最后一个字符。
那是什么?我在这个函数中创建了字符串:
char get_string(char *buf, int ble, FILE *fp, char del)
{
int i = 0;
int c;
char result;
memset(buf, 0, BUFLEN);
do {
c = fgetc(fp);
if (c == del) {
buf[i] = '\0';
result = c;
break;
} else if(c == '\n') {
buf[i] = '\0';
result = '\n';
break;
} else {
buf[i] = c;
i++;
}
} while (c != EOF);
return result;
}
然后在另一个函数中使用buf和结果:
char pair[BUFLEN];
char end;
do {
end = get_string(pair, BUFLEN, fp, ';');
printf("Result: %s\n",pair);
} while (pair != NULL);
上面的最后一次迭代打印出“结果:y”我不明白为什么。
答案 0 :(得分:9)
您正在使用do
- while
循环,这意味着您在测试EOF
之前正在执行循环体,因此您最终会放置EOF
在你的缓冲区中也是如此。 EOF
值-1将转换为与corresponds对应的字符范围。我建议您切换到更常见的while
循环,因为它更自然地处理这种情况。
答案 1 :(得分:8)
ÿ是字符的字形(在Unicode和许多ISO-8859-?编码中)具有序数值0xFF。该值也以十进制表示为255,在某些上下文中也用作“文件结尾字符”(又名EOF) - 尽管没有标准可以定义字符( AFAIK),值-1是当您尝试从耗尽的文件(“文件末尾”)中读取更多内容时以多种语言(例如C)返回的内容。
因此,在实践中,输出中的意外ÿ通常意味着您错误地解释了一个意图表示“结束某事”的字节(一个字节编码为所有位设置为1),就好像它是要显示的文字。
答案 2 :(得分:2)
'y'上面有两个点是字符0xFF(在latin-1中 - 控制台的默认代码页)。
0xFF作为8位有符号值为-1。
查找您将-1打印为char的位置(或使用-1作为char然后打印它)。
答案 3 :(得分:1)
当你“在一个循环中构建你的字符串”时,你还记得用'\0'
正确终止它吗?
如果循环将字符分配给字符数组,则最后一个数组项应为'\0'
。
好的,看到代码后,你正在终止字符串。
修改强>:
看起来你在字符串中包含了EOF字符。这是字符串未正确终止的一种情况。您应该在if-else结构中检查EOF并正确处理它。
我注意到另一件事:
从功能返回时,您正在为int c
分配char result
。编译器应警告您,您正在尝试将较大的数据类型放入较小的数据类型中。根据返回值的目的,我会考虑将返回数据类型更改为int
。
答案 4 :(得分:1)
你的if
语句以一个将字符放入缓冲区的else结尾,有两个缺点:
EOF
特殊“字符”,表示流的结束i
与BUFLEN
值进行比较,它不会检查缓冲区溢出。第一个问题是你的ÿ字符的原因,当流结束时,你将EOF
字符添加到缓冲区,然后循环终止。
修复方法是在您的if-else
语句中添加一个子句来过滤掉它,如下所示:
} else if (c != EOF) {
buf[i] = c;
i++;
}
在修复之前需要决定如何处理的第二个问题,但 应该。
答案 5 :(得分:0)
您没有正确地终止字符串。如果从 fp 读取永远不会返回“del”或“\ n”并且您达到EOF,则不会出现空终止符。你需要修改你的代码。