c语言中fread读取结构体,fread读取结构体注意事项

本文介绍了C语言中fread函数读取结构体的使用方法,强调了文本文件与二进制文件的区别,并提供了一个示例,展示如何读取包含三列数据的文本文件并按第二列内容排序。通过分析文件大小和换行符的影响,解释了读取过程中可能遇到的问题。最后,建议避免在处理文本文件时使用fread,推荐使用fscanf, fgets, fgetc等函数。" 110001813,10272241,Vue Echarts 时间轴数据处理与空值填充,"['前端开发', 'Vue', 'Echarts']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者 : 卿笃军

函数原型

size_t fread ( void *

buffer

, size_t

size

, size_t

count

, FILE *

stream

) ;

参 数

buffer

用于接收数据的

内存地址

size

要读写的字节数

,单位是字节

count

要进行读写多少个size字节的数据项,每个元素是size字节.

stream

输入流

返回值

实际读取的元素个数.如果返回值与

count不相同,则可能文件结尾或发生错误.

从ferror和feof获取错误信息或检测是否到达文件结尾.

C的文本读写和二进制读写:

C的文本方读写与二进制读写的差别仅仅体现在回车换行符的处理上.文本方式写时,每遇到一个'\n'(0AH换行符),它将其换成'\r\n'(0D0AH,回车换行),然后再写入文件;当文本读取时,它每遇到一个'\r\n'将其反变化为'\n',然后送到读缓冲区.二进制读写时,其不存在任何转换,直接将写缓冲区中数据写入文件.

那么,如果我们要用fread()来读取文本文件呢?下面我们来试一下:

新建一个.txt文件,命名为"f1.txt",然后在里面输入如下内容:

0818b9ca8b590ca3270a3433284dd417.png

注意上图中的光标位置,我们在最后一行也添加了一个回车~~~

(同时注意每一行字符个数一样多,有时候你看到一样多,其实不是一样多的,因为字符大小不一样,如:'w','i'不一样大)

在面我们来看一下文件大小:48字节

0818b9ca8b590ca3270a3433284dd417.png

咦,为什么会是48个字节呢?上面的文件中明明只有42个字符啊。这里就牵涉到windows记事本中的换行问题了:

"记事本中是用'\r\n'来实现换行的,并且在记事本中不显示出来"

哦!这下子明白了,原来我们敲了3个换行符。3*2 = 6 ,而6+42 = 48 刚刚好!!!

(当然,你也可以自己试一下,新建一个".txt"文件,在里面输入"123"然后保存,查看一下txt属性,这时候大小为3字节

然后你再打开txt在里面输入一个回车,保存,再查看一下属性,是不是变成5字节了?)

额,下面我们来实现以下读取文件,然后根据文件中的 第二列 中的字符串大小对 记事本中的行进行排序~~~

我们先构思一下要如何读取文件行,很简单,弄一个结构体:

typedef struct node

{

char a[4];

char b[8];

char c[4];

}LNode;

char a[4] :存放"123 "  (123后面还有一个空格也存放在a[]里面)

char b[8]  :存放"kbcdefg " (一直到20前面)

char c[4]  :存放"20\r\n"  (这里是要注意的)

另外还牵涉到一个问题,就是非字符串如何比较大小?这里引入了strncmp()函数。

#include

#include

#include

#include

#include

typedef struct node

{

char a[4];

char b[8];

char c[4];

}LNode;

int main()

{

FILE *fp1 = NULL, *fp2 = NULL;

struct _stat buf;

int i,j,n = 0;

LNode *fbuf = NULL, t;

fp1 = fopen("f1.txt","rb");

fp2 = fopen("f2.txt","wb");

_stat("f1.txt",&buf); //buf.st_size 文件大小

n = buf.st_size/(sizeof(LNode)); //获得文件行数

fbuf = (LNode *)malloc(buf.st_size);

for (i = 0; i < n; ++i)

fread(&fbuf[i],sizeof(LNode),1,fp1); //读文件

for (i = 1; i < n; ++i)

for (j = 0; j < n-i; ++j) //按照b排序

{

if (strncmp(fbuf[j].b,fbuf[j+1].b,7) < 0)

{

t = fbuf[j];

fbuf[j] = fbuf[j+1];

fbuf[j+1] = t;

}

}

for (i = 0; i < n; ++i) //写文件

fwrite(&fbuf[i],sizeof(LNode),1,fp2);

fclose(fp1);

fclose(fp2);

return 0;

}

如果你 strcut _stat结构体看不懂的话,参见这里:C语言中如何获得文件大小,

http://www.voidcn.com/article/p-mtewtfzc-qq.html

如下图,排好序的"f2.txt":

0818b9ca8b590ca3270a3433284dd417.png

当然,上面的结构体里面定义的全部是char类型的成员,不涉及结构体的字节对齐问题。

如果牵涉到结构体的字节对齐问题,可能操作起来会更加复杂。

所以,如果不是必要,请不要用fread()函数读取文本文件。fscanf(),fgets(),fgetc()等函数都能很好的读取文本文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值