【问题标题】:C - reading past end of file with fgetcC - 使用 fgetc 读取文件末尾
【发布时间】:2013-01-18 07:27:20
【问题描述】:

我遇到了最奇怪的事情,但我不太确定为什么会这样。基本上我需要做的是使用 fgetc 逐字节获取简单 ASCII 文件的内容。奇怪的是它起作用了,但后来我又添加了几个字符,突然间它添加了一个不存在的换行符,并读取到文件末尾或其他内容。从字面上看,我所做的只是

do {
    temp = (char*) checked_realloc (temp, n+1);
    e = fgetc(get_next_byte_argument);
    temp[n] = e;
    if (e != EOF)
      n++;
 }
while (e != EOF);

然后检查一下,我只是打印了每个字符

temp_size = strlen(temp)-1;
for(debug_k = 0; debug_k < temp_size; debug_k++){
  printf("%c", temp[debug_k]);
}

它会正确输出所有内容,只是它添加了一个不在文件中的额外换行符。在此之前,我有

temp_size = strlen(temp);

但随后它以某个未知字节(打印的乱码)结束。我尝试了 strlen(temp)-2 以防万一,它适用于那个特定的文件,但后来我在末尾添加了一个额外的“a”,它又坏了。

我真的很难过。我不知道它为什么这样做。

编辑:checked_realloc 只是 realloc 但通过快速检查以确保我没有内存不足。我意识到这不是最有效的方法,但我更担心为什么我似乎在神奇地读取额外的字节。

【问题讨论】:

  • 为了使strlen(temp) 工作,文件内容后应该有一个终止NUL 字符。您没有显示添加此最终 \0 的代码 - 你有吗?
  • 如果checked_realloc()只是realloc,在尝试读取之前尝试初始化内存为0。
  • 噢噢噢……呃。我完全忘记了这一点。谢谢!顺便说一句,由于最后一个字符是 EOF,NULL 应该替换它还是紧随其后?我可能会通过反复试验来弄清楚,但我不妨问问
  • @user1777900 将 EOF 替换为 NULL。我编辑了我的答案来解决这个问题。
  • EOF 不是字符 -- EOF 是当您到达文件末尾时 fgetc 返回的整数。

标签: c file fgetc


【解决方案1】:

编写此类操作的更安全的方法是:

  1. 如果您在 realloc 之前分配内存,则在使用零之前 memset 内存块。并且每次重新分配时,将其初始化为零。
  2. 如果您使用内存来访问字符串或在该内存上使用字符串函数,请始终确保使用 NULL 字节终止该内存。

do{
    temp = (char*) checked_realloc (temp, n+1);//I guess you are starting n with 0? 
    temp[n]=0;
    e = fgetc(get_next_byte_argument);
    temp[n] = e;
    if (e != EOF)
        n++;
} while (e != EOF);
temp[n]=0;
n=0;

我想上面的代码更改应该可以解决您的问题。你不再需要 strlen -1 了。 :)

干杯。

【讨论】:

  • 看来已经做到了!奇怪的是,我的文件中仍然没有换行符,但它是一致的。可能没有换行符,也可能是乱码。
  • 不。 OP 正在使用 fgetc 初始化 e 并将 temp[n] 存储为 e 的值。如果 OP 获得 EOF,则 n++ 不会发生,并且 temp[n] 在达到 while 条件之前仍将包含 EOF。在它退出后,tem[n] 将始终包含 EOF(除非循环因其他原因退出)和 temp[n ]=0 在 while 循环之后将安全地覆盖 temp[n] 中包含的 EOF。 :)
【解决方案2】:

听起来你忘了空终止你的字符串。在while 之后添加temp[n] = 0;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    • 2022-01-21
    相关资源
    最近更新 更多