gpt4 book ai didi

c - 了解 fwrite() 行为

转载 作者:行者123 更新时间:2023-11-30 21:22:16 24 4
gpt4 key购买 nike

  1. 当我使用 fwritestdout 时,它会变成未定义的结果?
  2. fwritefread 函数中的 size_t count 参数有何用途?
#include<stdio.h>

struct test
{
char str[20];
int num;
float fnum;
};

int main()
{
struct test test1={"name",12,12.334};

fwrite(&test1,sizeof(test1),1,stdout);

return 0;
}

输出:

 name                   XEA
Process returned 0 (0x0) execution time : 0.180 s
Press any key to continue.

当我对文件使用 fwrite 时

 #include<stdio.h>
#include<stdlib.h>

struct test
{
char str[20];
int num;
float fnum;
};

int main()
{
struct test test1={"name",12,12.334};
FILE *fp;

fp=fopen("test.txt","w");

if(fp==NULL)
{
printf("FILE Error");
exit(1);
}

fwrite(&test1,sizeof(test1),1,fp);

return 0;
}

该文件还包含这样的内容

 name                   XEA
  1. 为什么输出是这样的?
  2. 当我将size_t count设置为5时,它也变成了未定义的结果。这个论证的目的是什么?

最佳答案

按照您使用它的方式,fwrite正在写入“二进制”输出,它是您的 struct test 的逐字节表示形式和内存中一样。这种表示方式通常是人类可读的。

当你写的时候

struct test test1 = {"name", 12, 12.334};

你在内存中得到一个结构,它可能像这样表示(所有字节值都是十六进制):

test1: str: 6e 61 6d 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
num: 0c 00 00 00
fnum: 10 58 45 41

具体:0x6e , 0x61 , 0x6d ,和0x65"name" 中字母的 ASCII 代码。您的str数组的大小为 20,因此字符串 name以 0 结尾,然后用 15 个以上的 0 字符填充。 0x0c是数字 12 的十六进制表示形式,我假设输入 int在你的机器上是 32 位或 4 个字节,所以那里还有 3 个 0。 (另外,我假设您的机器是“小端”,4 字节数量中的最低有效字节如 0x0000000c 首先出现在内存中。)最后,在 IEEE-754 format 中。您的机器使用的数字 12.334 以 32 位单精度 float 表示为 0x41455810 ,再次以相反的顺序存储在内存中。

因此,这 28 个字节(可能还加上一些填充,我们现在不用担心)正是写入屏幕或文件的字节。字符串“name”可能是人类可读的,但其余的字面意思都是“binary garbage”。恰好组成 float 12.334的三个字节,即0x58 , 0x45 ,和0x41 ,对应于 ASCII 中的大写字母 X , E ,和A ,这就是您在输出中看到这些字符的原因。

这是将程序的输出传递到“hex dump 实用程序的结果:

 0  6e 61 6d 65 00 00 00 00  00 00 00 00 00 00 00 00   name............
16 00 00 00 00 0c 00 00 00 10 58 45 41 .........XEA

您可以看到字母name开头,以及字母 XEA最后,以及中间的所有 0 和其他二进制字符。

如果您使用的是 Unix 或 Linux(或 Mac OS X)系统,则可以使用类似 od 的工具。或 hexdump 获得类似于我所展示的十六进制转储。

<小时/>

您询问 fwrite 的“count”参数。 fwrite从字面上看,它是为写出二进制结构而设计的,就像您正在做的那样。它的函数签名是

size_t fwrite(void *ptr, size_t sz, size_t n, FILE *fp);

如您所知,ptr是指向您正在编写的数据结构的指针,并且 fp是您正在写入的文件指针。然后你说你想写 n (或“计数”)元素,每个尺寸 sz .

你打过电话

fwrite(&test1, sizeof(test1), 1, fp);

表达式sizeof(test1)给出的大小为 test1以字节为单位。 (正如我上面提到的,它可能是 28 左右。)当然,您正在编写一个结构体,因此传递 sizeof(test1)1szn完全合理、正确。

调用也不是不合理或不正确的

fwrite(&test1, 1, sizeof(test1), fp);

现在你告诉fwrite写入 28 个字节,每个字节大小为 1。(当然,一个字节的大小始终为 1。)

关于fwrite的另一件事(如 @AnttiHaapala 在评论中所述):当您将​​二进制数据写入文件时,您应该指定 b打开文件时标记:

fp = fopen("test.txt", "wb");
<小时/>

最后,如果这不是您想要的,如果您想要人类可读的文本输出,那么 fwrite这不是你想要的。你可以使用类似的东西

printf("str: %s\n", test1.str);
printf("num: %d\n", test1.num);
printf("fnum: %f\n", test1.fnum);

或者,到您的文件:

fprintf(fp, "str: %s\n", test1.str);
fprintf(fp, "num: %d\n", test1.num);
fprintf(fp, "fnum: %f\n", test1.fnum);

关于c - 了解 fwrite() 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58254839/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com