【问题标题】:C - Writing to file gives me symbols instead of numbersC - 写入文件给我符号而不是数字
【发布时间】:2015-02-10 03:55:22
【问题描述】:

我正在写入一个 .ppm 文件,到目前为止,我只是通过向它写入 0 和 1 来测试它。当我在记事本中打开文件时,数字显示为符号。但是当我在写字板或 Microsoft Word 中打开它时,会出现数字。代码肯定没有问题,是记事本的错吗?我试图通过谷歌查找,但我找不到任何东西。 本质上,我正在做的是扩展一个文件,其中包含 (1 1 1 1) 到 (1 0 0 1 0 0 1 0 0 1 0 0) 之类的值,它们是红色像素,然后在其中添加绿色和蓝色值同样的方式。

我得到‱‰‰‱‰‰‱‰‰‱‰‰, 而不是 100100100100。

代码是:

#include <stdio.h>

int redArray[128][256 * 3];

int main(void) {
int x;
int y;
FILE *redFile = NULL;

imagePixels = fopen("image.ppm", "w");
redFile = fopen("image.red", "r");

readRed(redFile);

for (y = 0; y < 128; y++) {
        for (x = 0; x < 256 * 3; x += 3) {
            redArray[y][x] = 1;
    }
}

for (y = 0; y < 1; y++) {
    for (x = 0; x < 256 * 3; x++) {
        fprintf(imagePixels, "%d ", redArray[y][x]);
    }
}

fclose(redFile);
fclose(imagePixels);

return 0;
}

// This function is in a different .c file. I completely forgot to add it here but I'll leave at        the '#include' business.
void readRed(FILE *colourFile) {
   for (y = 0; y < 128; y++) {
       for (x = 0; x < 256; x++) {
            fscanf(redFile, "%d", &redArray[y][x]);
       }
   }
}

【问题讨论】:

  • redArray = fopen("image.red", "r"); --> redFile = fopen("image.red", "r"); imagePixels 在哪里?
  • 这行应该是什么意思 redArray = fopen("image.red", "r"); ????
  • 由于你没有任何换行符,我认为记事本可能存在行长问题。
  • @iharob 哦,是的,image.red 是我正在读入 redArray 的文本文件,然后它将与 greenArray 和 blueArray 合并以生成 imagePixels 或更确切地说是 image.ppm。
  • 我想我找到了原因,看看我的回答。

标签: c file symbols writing


【解决方案1】:

您需要在操作之前打开文件并读出数据。现在您正在打开FILE * redArray,然后直接读取它,就像它是一个数组一样。这是一个文件句柄。

您必须首先将数据读入数组,例如: (刷自here

int fileSize;
int * contents;

//Seek to the end of the file to determine the file size
fseek(redArray, 0L, SEEK_END);
fileSize = ftell(redArray);
fseek(redArray, 0L, SEEK_SET);

//Allocate enough memory (add 1 for the \0, since fread won't add it)
contents = malloc(fileSize+1);

//Read the file 
size_t size = fread(contents,1,fileSize,redArray);

//Close the file
fclose(redArray);

【讨论】:

    【解决方案2】:

    你在声明

    int redArray[128][256 * 3];

    并为其分配句柄

    redArray = fopen("image.red", "r");

    我想你的意思是:

    redFile = fopen("image.red", "r");

    【讨论】:

      【解决方案3】:

      由于您得到的是垃圾字符,而不是数字(并且您使用了 %d 格式的 fprintf),我的猜测是,您的程序以一种编码(可能是 UTF-8)写出数据,而记事本将其解释为不同的东西(可能只是 ASCII)。

      您可能想浏览一下您构建程序的开发环境,看看它默认输出的字符编码是什么。

      http://kunststube.net/encoding/ 有一篇关于字符编码的大论文

      还有一篇关于记事本如何解释字符编码的 StackOverflow 文章

      How windows notepad interpret characters

      在最后一篇文章中有一些有用的链接。

      由于您说您只是在测试写入文件的能力,因此包含输入文件代码可能会误导一些读者。

      【讨论】:

      • 我刚试着写了一个我当场组成的数组,数字看起来很好......
      • 您的数组在您提供的代码示例中未初始化;您可能很幸运,您没有明确设置的数组成员得到 0。
      【解决方案4】:

      问题与记事本处理文件有关。记事本查找前 512 个字节以确定文件的编码。当没有指定 BOM 时,它会尝试猜测。您的文件很可能被视为 Unicode。它在我的机器上(Unicode(UTF16 LE)),查看文件->编码->更多)。这就是你得到这些字符的原因:

      ‰ 的代码点是 U2030。您正在(反复)编写1 0 0,它以字节为单位,以 Ascii 编码并以十六进制表示,转换为

      3120302030

      您可以看到为什么每 3 个字符打印 2 次 ‰。对于第一个,我只是认为记事本被扔掉并显示不可打印的字符。

      在我的机器上进行测试时,如果我在第一行最多 512 个字符之后引入\n(这很重要,因为第二行可能超过 6000 个字符)我可以在记事本中加载文件但不止于此。

      【讨论】:

      • 非常感谢。对于我的代码中的错误,我深表歉意,我迅速对其进行了编辑,结果发现它很糟糕。
      猜你喜欢
      • 2010-10-31
      • 2018-11-24
      • 2017-04-10
      • 2013-07-19
      • 1970-01-01
      • 1970-01-01
      • 2017-08-28
      • 2021-10-10
      • 1970-01-01
      相关资源
      最近更新 更多