`
卿笃军
  • 浏览: 3919 次
文章分类
社区版块
存档分类
最新评论

fread读取结构体注意事项

 
阅读更多

作者 : 卿笃军

函数原型

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'',然后送到读缓冲区.二进制读写时,其不存在任何转换,直接将写缓冲区中数据写入文件.

参考文章:JianKun的博客,文本文件与二进制文件区别,http://www.cnblogs.com/zhangjiankun/archive/2011/11/27/2265184.html

 

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

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

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

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

咦,为什么会是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 <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <malloc.h>
#include <string.h>

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://blog.csdn.net/qingdujun/article/details/25157107

 

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

 

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

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

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

如果你想了解结构体的字节对齐情况,你可以参见:结构体在内存中所占字节大小计算,http://blog.csdn.net/qingdujun/article/details/24844681

 

我的CSDN博客:http://blog.csdn.net/qingdujun/article/details/25299421

我的博客园:http://www.cnblogs.com/qingdujun/p/3716053.html

分享到:
评论

相关推荐

    将结构体写入二进制文件

    五、注意事项 1. 文件操作需处理异常情况,如打开失败、写入/读取错误等。 2. 在跨平台操作时,要考虑不同操作系统对二进制文件的字节序(大端或小端)处理可能存在的差异。 3. 结构体中的成员可能会有填充字节,以...

    file_to_struct.rar_结构体

    6. **注意事项**: - 当从文件读写结构体时,确保读写顺序与写入时一致,否则可能导致数据混乱。 - 文件模式错误(如使用文本模式代替二进制模式)可能导致数据损坏或不匹配。 - 记得检查文件操作的返回值,以...

    C++读取bmp文件

    7. 注意事项: - BMP文件的像素数据存储方式可能会有小端序和大端序之分,需要根据系统字节序进行调整。 - 当处理不同尺寸或颜色深度的BMP文件时,需要相应地调整内存分配和数据读取的逻辑。 通过以上知识点,你...

    C语言读取BMP文件

    #### 四、注意事项 - 在实际开发中,应考虑文件读写错误处理,例如检查`fread`和`fwrite`是否成功完成。 - 使用完内存后,记得释放分配的内存以避免内存泄漏。 - 当处理非24位位图时,还需要额外处理调色板数据。 ...

    C语言读取、存储、显示BMP图像

    8. **注意事项** 在处理BMP文件时,必须考虑到不同平台可能的字节序差异(大端或小端)。此外,确保正确处理文件指针的位置,避免内存泄漏,并检查所有文件操作是否成功。 总结,理解BMP文件格式及其结构,掌握...

    C二进制文件读写操作-C教程共4页.pdf.zip

    2. 读取数据:同样假设我们要读取结构体数组,可以使用`fread()`,例如`fread(array, sizeof(struct), count, fp);`,这里`array`是用来存放读取数据的内存区域。 3. 检查读取状态:可以用`feof()`或`ferror()`检查...

    c语言进阶c语言学习,c语法,c例子,c注意事项,学习c的最好书籍,简单

    对于想要深入学习C语言的人来说,理解其基本概念、掌握语法、熟悉常用例子和注意事项至关重要。此外,选择一本好的C语言学习书籍也是提升技能的关键。 C语言进阶学习包括以下几个主要方面: 1. **基本语法**:...

    C语言文件读写操作详解:掌握核心技巧,提升编程效率.pdf

    `fread` 函数用于二进制读取,适用于读取结构体等非文本数据。在上述代码中,每次读取一个 `Data` 结构体大小的数据,并输出读取的内容。 #### 五、写入文件 C 语言同样提供了多种文件写入函数,如 `fputc`、`...

    程序设计-二进制的方式读写文件.pptx

    二进制文件读写的一个重要注意事项是,当文件被读写时,文件指针会自动移动,因此在处理大文件或多个数据结构时,要确保正确管理文件指针的位置,防止数据丢失或覆盖。 总的来说,掌握二进制方式的文件读写是程序...

    C课程设计通讯录

    - **注意事项**:在读取数据前需要检查文件是否为空,以避免不必要的错误提示。 - **添加记录函数`enter()`与`append()`** - **功能**:向通讯录文件中添加新的记录。 - **解析**:这两个函数实际上实现了相同的...

    matlab开发-struct2ini.zip.zip

    10. **测试和文档**:为了确保函数的正确性和可维护性,开发者需要编写测试用例来验证功能,并编写清晰的文档说明如何使用这个功能,包括输入参数、返回值、注意事项等。 综上所述,`matlab开发-struct2ini.zip`...

    C语言编程实战:文件操作基础,掌握fopen、fprintf、fread、fwrite等核心函数,实现高效数据存储与检索

    #### 四、注意事项 1. **错误处理**:文件操作过程中可能会遇到各种错误,如文件不存在、权限不足等,因此在实际应用中需要添加适当的错误处理代码。 2. **模式选择**:写入文件时,如果文件已经存在,使用"w"模式...

    c语言顺序文件-扫描版.rar

    以上就是关于C语言中处理顺序文件的一些核心知识点,包括文件的打开、读写、定位、关闭等操作,以及在实际应用中的一些注意事项。理解并熟练掌握这些概念对于任何C语言开发者来说都是至关重要的。

    Linux系统函数调用文件内容操作篇[定义].pdf

    根据提供的文档信息,我们可以归纳出以下几个关键的 Linux 文件操作相关的知识点: ### 1. `clearerr` — 清除文件流的错误标志 ...了解它们的使用方法和注意事项对于编写高效、可靠的程序至关重要。

    家庭财务管理系统代码C++

    其他注意事项 - 在实际开发中,为了提高代码的可读性和可维护性,通常会使用更现代的 C++ 语法特性,如智能指针、范围 for 循环等。 - 此外,考虑到安全性问题,应该避免使用像 `gets` 这样的函数,因为它可能会...

    三月全国计算机等级考试二级C语言上机题.pdf

    6. 文件操作注意事项: - 文件操作前必须检查是否成功打开,如`fp = fopen("file1.txt", "w")`。 - 关闭文件非常重要,防止数据丢失,如`fclose(fp)`。 - 当需要对文件进行读写操作时,要确保文件以正确的模式...

    C语言转换大智慧数据

    ### 三、注意事项 在实际操作中,需要注意以下几点: 1. **文件路径和名称**:确保提供的文件路径正确无误,且具有相应的读写权限。 2. **数据类型匹配**:在读取时,确保`fread`函数读取的数据类型与`struct gpjg...

    c语言文件读写操作代码.docx

    #### 四、注意事项 1. **文件路径**:确保提供正确的文件路径。如果是当前目录下的文件,只需提供文件名即可。 2. **错误处理**:在实际开发中,应该加入更多的错误处理机制,例如检查 `fopen()` 是否成功打开文件...

    DBF文件的操作经典详解(C语言版)

    五、注意事项 1. 数据类型转换:DBF文件中的数据类型可能与C语言中的不完全匹配,需要进行适当的转换。 2. 错误处理:在文件操作过程中,应添加错误检查代码,如打开文件失败、内存分配失败等。 3. 编码问题:DBF...

Global site tag (gtag.js) - Google Analytics