【问题标题】:fgetc dropping characters when reading 2d pixel map with for loopfgetc 在使用 for 循环读取 2d 像素图时丢弃字符
【发布时间】:2016-08-10 19:33:04
【问题描述】:

我正在从 PPM 文件中输入 2d 像素数组,我正在测试的是宽度和长度为 5 的像素数组。此外,我知道在 rgb 的 ppm 文件中,它具有 3 个颜色值而不仅仅是一个。在编写此代码之前我已经忘记了这一点,但是即使对其进行了更新,问题仍然存在,并且问题仍然以相同的方式存在。我已将问题简化为数组以隔离问题。据我所知,这似乎既是删除字符,又是用换行符替换一些字符。任何有关为什么会发生这种情况的见解将不胜感激,如果我忘记添加一些内容,我会在知道后立即更新。

#include <stdio.h>

int main(int args, char *argv[]) {
    int w = 5, h = 5;

    FILE *f = fopen(argv[1], "rb");
    int c = 'a';//I am setting this so as to avoid the off chance of c being defined as EOF
    for(int i = 0; i < h && c != EOF; i++) {
        for(int j = 0; j < w && (c = fgetc(f)) != EOF; j++) printf("%c", c);
        fgetc(f);//To remove the '\n' character I am not using fgets because it stops at '\n' character and it is possible for a rgb value to be == to '\n'
        printf("\n");
    }
    fclose(f);
    return 0;
}

我正在使用的测试文件:

12345
abcde
12345
abcde
12345

我得到的输出:

12345

abcd

123
5
ab
de
1

提前致谢!

编辑:这是在 Windows 10 命令提示符下运行的

【问题讨论】:

  • 我敢打赌这是在 Windows 机器上,对吧?或者至少你的输入文件有 crlf 行结尾。
  • 是的,导致“丢失”字符在每一行中向后移动一个位置 - 这意味着额外的 fgetc 正在丢弃它。
  • 确实,看起来您的文件实际上是一个带有 Windows 行结尾的文本文件,即使您以二进制模式打开它也是如此。提示,使用调试器,打印读取字符的 ASCII 值而不是字符本身,不要在一行里塞这么多东西,这样更容易调试。
  • ppm 似乎是一个文本文件。也许以文本模式打开文件?
  • @chux 取决于“幻数”,P4 P5 和 P6(ppm RGB)实际上是二进制的。

标签: c for-loop multidimensional-array c11 fgetc


【解决方案1】:

问题在于,Windows 机器上的 '\n' 实际上最终会生成两个字符,一个回车符(ASCII 代码 13)和一个换行符(ASCII 代码 10)。当您以二进制模式打开文件时,这些行结尾不会转换回单个字符。您只考虑了这些字符中的一个,因此您阅读的每一行都是一个字符。

为了说明这一点,请将您的 printf("%c", c);" 替换为 printf("%d ", c);。我得到以下输出:

49 50 51 52 53 
10 97 98 99 100 
13 10 49 50 51 
53 13 10 97 98 
100 101 13 10 49

你可以看到那些 10 和 13 的变化。

现在尝试添加第二个fgetc(f); 来吃换行符,它会更好地工作。但是请记住,这仅适用于具有 CRLF 行结尾的文件。把它移植到Linux或Mac上,你会遇到更多的麻烦。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多