【问题标题】:Getting '�' or '@' symbol when reading from text file with fread使用 fread 从文本文件读取时获取“�”或“@”符号
【发布时间】:2023-03-03 05:39:18
【问题描述】:

我想从一个文本文件中读取 80 个字符,将它们保存为一个字符串,然后打印该字符串以进行验证。 我正在使用 fread 并且有这个代码:

char message[80];
size_t nread = fread(message, 1, sizeof(message), fp);
printf("Message received: \"__%s__\"\n", message);

输出是:

收到的消息:“__我很想改变世界,但他们不会
��__"

当整个短语不在文件中时

和:

__我很想改变世界,但他们不会给我源代码
@__

当整个短语都在文件中时。

我尝试删除它并重写文本,但我再次得到相同的输出。

怎么了?字符集的东西?

【问题讨论】:

  • @cnicutar,如果它读作80,那将是message 末尾的一个。
  • @hmjd 是的,nread 必须在此之前检查。或者只是将 sizeof - 1 传递给fread

标签: c file io fread


【解决方案1】:

fread() 不会空终止缓冲区,prinf("%s") 期望缓冲区空终止。由于缓冲区不是空终止的,printf() 将继续读取,直到找到空终止符,并在此过程中打印出任何垃圾。

要么null终止缓冲区,记得为null终止符留出空间:

char message[81]; /* Increased by 1 for null terminator. */
size_t nread = fread(message, 1, sizeof(message) - 1, fp);
message[nread] = 0;
printf("Message received: \"__%s__\"\n", message);

或指示printf() 仅打印使用"%.*s" 格式说明符读取的字符数:

printf("Message received: \"__%.*s__\"\n", nread, message);

【讨论】:

  • 太棒了!我认为它确实使用 message[nread] = '\0'; 终止了缓冲区。所以我想我会终止它。但是你能解释一下你在用 printf 做什么吗? '*' 是指 nread 变量?
  • @Chris, "%.*s" 是一个格式说明符,需要两个参数:长度和缓冲区。它指示printf() 打印来自message 的第一个nread 字符,从而消除了message 中对空终止符的要求。
  • 谢谢!我实际上不知道 printf 的这一点。
猜你喜欢
  • 2016-04-20
  • 1970-01-01
  • 2012-08-06
  • 1970-01-01
  • 2019-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多