-2

我正在使用 C 的 fwrite 函数将 3 个整数的数组写入文件,但是使用 gedit(使用 Unicode UTF-8)打开输出文件时,出现以下错误:

There was a problem opening the file.  The file you opened has invalid characters.  If you continue editing this file, you could corrupt the document.

这是相关的代码片段:

char* imageFile = "image.txt";
FILE* imageFilePtr = fopen(imageFile, "w");

int scores[3] = {69, 70, 71};
fwrite(scores, sizeof(int), sizeof(scores), imageFilePtr);

当我使用诸如“xxd”之类的十六进制阅读器时,我在终端中得到以下信息:

0000000: 4500 0000 4600 0000 4700 0000 7031 7108  E...F...G...p1q.
0000010: 0830 7108 2987 0408 2087 0408 0460 cebf  .0q.)... ....`..
0000020: 0100 0000 0000 0000 0000 0000 0000 0000  ................

请记住,在我的环境中,sizeof(int) 是 4 个字节。因此,我可以看到十进制的 69、70 和 71 如何以十六进制的 45、46 和 47 形式打印到文件中,如 xxd 所示。但是,“4700 0000”之后的所有其他字节来自哪里?而且,为什么我不能用文本编辑器打开输出文件“image.txt”来查看显示十进制数字 69、70 和 71 的文件?

4

2 回答 2

5
fwrite(scores, sizeof(int), sizeof(scores), imageFilePtr);
                            ^^^^ Wrong

在你的情况下,sizeof(scores)sizeof(int)*3。您只需要 3 个。您可以使用:

fwrite(scores, sizeof(int), 3, imageFilePtr);

或者更健壮,使用:

fwrite(scores, sizeof(int), sizeof(scores)/sizeof(int), imageFilePtr);

您还可以使用:

fwrite(scores, 1, sizeof(scores), imageFilePtr);

或者

fwrite(scores, sizeof scores[0], sizeof scores/sizeof scores[0], imageFilePtr);
于 2015-10-07T21:36:24.150 回答
1

我可以在这里看到两个问题。一种是您试图在文本编辑器中打开二进制文件。第二个是在写入二进制文件时出现缓冲区读取溢出。我先讲第二个。

fwrite 函数将“元素大小”和“元素计数”作为参数。您已将元素的大小设置为 sizeof(int),这是正确的,但是对于您所做的 sizeof(scores) 计数,实际上是 3*sizeof(int),而您实际上需要值 3。假设 int 大小为 4 (32 位)然后计数值设置为 12。这意味着它正在尝试将 48 个字节写入文件而不是 12。另外 36 个字节是堆栈上的读取溢出。

要获取数组中的元素数,您可以使用:sizeof(scores)/sizeof(scores[0])。

fwrite(scores, sizeof(int), sizeof(scores)/sizeof(scores[0]), imageFilePtr);

我会为此使用宏,所以我可以去

fwrite(scores, sizeof(int), NumOfElements(scores), imageFilePtr);

其中 NumOfElements 定义为:

#define NumOfElements(Array) (sizeof(Array)/sizeof(Array[0]))

现在解决第一个问题。我相信您正在尝试将 3 个整数写入文本文件。fwrite 函数写入二进制数据。您要使用的是 fprintf。这与 printf 的工作方式相同,但可以让您写入文件。但是你不能用一个 fprintf 写一个数字数组,所以你必须有一个循环。

for( i=0; i<NumOfElements(scores); i++ )
{
    fprintf( imageFilePtr, "%u\n", scores[i] );
}

这会将每个数字单独写入文件中。

于 2015-10-08T01:41:06.447 回答