文档章节

fwrite()函数与fread()函数

天蚕宝衣
 天蚕宝衣
发布于 2017/08/14 18:15
字数 1276
阅读 13
收藏 1

fwrite和fread是以记录为单位的I/O函数,fread和fwrite函数一般用于二进制文件的输入输出。

#include <stdio.h>
size_t fread (void *ptr,       size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

返回值:读或写的记录数,成功时返回的记录数等于nmemb,出错或读到文件末尾时返回的记录数小于nmemb,也可能返回0。

freadfwrite用于读写记录,这里的记录是指一串固定长度的字节,比如一个int、一个结构体或者一个定长数组。参数size指出一条记录的长度,而nmemb指出要读或写多少条记录,这些记录在ptr所指的内存空间中连续存放,共占size *nmemb个字节,fread从文件stream中读出size *nmemb个字节保存到ptr中,而fwriteptr中的size *nmemb个字节写到文件stream中。

nmemb是请求读或写的记录数,freadfwrite返回的记录数有可能小于nmemb指定的记录数。例如当前读写位置距文件末尾只有一条记录的长度,调用fread时指定nmemb为2,则返回值为1。如果当前读写位置已经在文件末尾了,或者读文件时出错了,则fread返回0。如果写文件时出错了,则fwrite的返回值小于nmemb指定的值。下面的例子由两个程序组成,一个程序把结构体保存到文件中,另一个程序和从文件中读出结构体。

注意

(1)写操作fwrite()后必须关闭流fclose()。
(2)不关闭流的情况下,每次读或写数据后,文件指针都会指向下一个待写或者读数据位置的指针。

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

#include "freadandfwrite.h"

#include "atlbase.h"
#include "atlstr.h"

struct record 
{
	char name[10];
	int age;
};

int main(void)
{
	struct record array[2] = {{"Ken", 24}, {"Knuth", 28}};
	FILE *fp = fopen("recfile", "w");
	if (fp == NULL) 
	{
		perror("Open file recfile");
		exit(1);
	}
	fwrite(array, sizeof(struct record), 2, fp);
	fclose(fp);

    /*
    生成的文件recfile不能直接打开。
    原因:我们把一个struct record结构体看作一条记录,由于结构体中有填充字节,每条记录占16字节,
    把两条记录写到文件中共占32字节。该程序生成的recfile文件是二进制文件而非文本文件,因为其
    中不仅保存着字符型数据,还保存着整型数据24和28(在od命令的输出中以八进制显示为030和034)。
    注意,直接在文件中读写结构体的程序是不可移植的,如果在一种平台上编译运行writebin.c程序,
    把生成的recfile文件拷到另一种平台并在该平台上编译运行readbin.c程序,则不能保证正确读出
    文件的内容,因为不同平台的大小端可能不同(因而对整型数据的存储方式不同),结构体的填充方式
    也可能不同(因而同一个结构体所占的字节数可能不同,age成员在name成员之后的什么位置也可能不同)。
    通过readrec程序读取文件recfile的内容,说明writerec程序的确记录成功写入recfile中。
    */
	read();

	// fread()、fwrite()的第二种使用方法。
	writeData();
	readData();

	return 0;
}

int read(void)
{
	struct record array[2];
	FILE *fp = fopen("recfile", "r");
	if (fp == NULL)
	{
		perror("Open file recfile");
		exit(1);
	}
    /*
    由于程序生成的文件是二进制文件而非文本文件,因此,不用机器,整数的表达不同,
    所以无法直接打开生成文件。可通过fread函数检验数据是否写入文件。
    */
	fread(array, sizeof(struct record), 2, fp);
	OutputDebugPrintf("Name1: %s\t\nAge1: %d\n", array[0].name, array[0].age);
	OutputDebugPrintf("Name2: %s\t\nAge2: %d\n", array[1].name, array[1].age);
	fclose(fp);
	return 0;
}

void OutputDebugPrintf(const char *strOutputString, ...)
{
	char strBuffer[4096] = {0};
	va_list vlArgs;
	va_start(vlArgs, strOutputString);
	_vsnprintf_s(strBuffer, sizeof(strBuffer) - 1, strOutputString, vlArgs);
	// vsprintf(strBuffer,strOutputString,vlArgs);
	va_end(vlArgs);
	OutputDebugString(CA2W(strBuffer));
}

void writeData(void)
{
	FILE * pFile;
	int buffer[] = {1, 9, 9, 3};

	/* 
	pFile = fopen("myfile", "wb") 运行完这句话,则文件myfile读到内存中,
	并且指针pFile指向这句话。
	*/
	if ((pFile = fopen("myfile", "wb")) == NULL)
	{
		// 如果创建myfile失败,指针pFile指向空间为空,则在控制台显示"can't open the file"。
		OutputDebugPrintf("can't open the file");
		exit(0);
	}
	else
	{
		OutputDebugPrintf("文件myfile创建成功。\n");
	}
	// unbroken data could be write (demo is 4 times)  
	// 存储到文件的时候,1次存储1个字节,总共存储16次。
	fwrite(buffer, sizeof(char), 16, pFile);
	OutputDebugPrintf("将数据写入到文件myfile中成功。\n");
	fclose(pFile);
}

void readData(void)
{
	FILE *fp;
	// int buffer[4];
	int *buffer;
	if ((fp = fopen("myfile", "rb")) == NULL)
	{
		OutputDebugPrintf("can't open the file");
		exit(0);
	}
	else
	{
		OutputDebugPrintf("文件myfile读取到内存中成功。\n");
	}
	/*
	if (fread(buffer, sizeof(int), 4, fp) != 4)
	{
		printf("file read error\n");
		exit(0);
	}
	*/
	/* buffer = (int *)malloc(sizeof(int)); */
	buffer = (int *)malloc(sizeof(int));
	int label[4];
	for (int i = 0; i < 4; i++)
	{
		/* 
		读取文件的时候,1次读取4个字节,总共读取4次。
		*/
		fread(buffer, sizeof(int), 4, fp);
		label[i] = *buffer;
		buffer++;
	}
	fclose(fp);
	OutputDebugPrintf("将文件myfile中的数据读取到buffer、数组label[]中成功。\n");
	for (int i = 0; i < 4; i++)
	{
		OutputDebugPrintf("label[%d] = %d\n", i, label[i]);
	}
}

程序运行结果如下:

© 著作权归作者所有

天蚕宝衣
粉丝 28
博文 246
码字总数 181517
作品 0
天津
私信 提问
基本文件操作,fopen fwrite fread函数使用以及示例

本文主要介绍fopen()、fwrite()、fread()函数使用以及示例 fopen()函数 作用: 在C语言中fopen()函数用于打开指定路径的文件,获取指向该文件的指针。 函数原型: 打开UC浏览器 查看更多精彩图...

这个人很懒什么都没留下
03/12
0
0
转:文件系统read,write缓存,有点意思

当我们在linux系统下写程序的时候,经常会读文件或者写文件,既然要操作文件,就会用文件操作函数,其中涉及读写的不乏有read/write或者fread/fwrite,但是我们应该选择哪一种呢,少安毋躁,...

臧教授
2018/11/21
52
0
文件操作:fread()和fwrite()

fread和fwrite函数功能 用来读写一个数据块。 一般调用形式 fread(buffer,size,count,fp); fwrite(buffer,size,count,fp); 说明 (1)buffer:是一个指针,对fread来说,它是读入数据的存放地...

野渡书生
2016/03/11
13
0
C语言编程学习:C语言以数据块的形式读写文件

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你看世界
2018/05/24
0
0
C语言自学完备手册(32)——文件

版权声明: https://blog.csdn.net/lfdfhl/article/details/83752060 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–o...

谷哥的小弟
2018/11/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

只需一步,在Spring Boot中统一Restful API返回值格式与统一处理异常

统一返回值 在前后端分离大行其道的今天,有一个统一的返回值格式不仅能使我们的接口看起来更漂亮,而且还可以使前端可以统一处理很多东西,避免很多问题的产生。 比较通用的返回值格式如下:...

晓月寒丶
昨天
59
0
区块链应用到供应链上的好处和实际案例

区块链可以解决供应链中的很多问题,例如记录以及追踪产品。那么使用区块链应用到各产品供应链上到底有什么好处?猎头悬赏平台解优人才网小编给大家做个简单的分享: 使用区块链的最突出的优...

猎头悬赏平台
昨天
28
0
全世界到底有多少软件开发人员?

埃文斯数据公司(Evans Data Corporation) 2019 最新的统计数据(原文)显示,2018 年全球共有 2300 万软件开发人员,预计到 2019 年底这个数字将达到 2640万,到 2023 年达到 2770万。 而来自...

红薯
昨天
65
0
Go 语言基础—— 通道(channel)

通过通信来共享内存(Java是通过共享内存来通信的) 定义 func service() string {time.Sleep(time.Millisecond * 50)return "Done"}func AsyncService() chan string {retCh := mak......

刘一草
昨天
58
0
Apache Flink 零基础入门(一):基础概念解析

Apache Flink 的定义、架构及原理 Apache Flink 是一个分布式大数据处理引擎,可对有限数据流和无限数据流进行有状态或无状态的计算,能够部署在各种集群环境,对各种规模大小的数据进行快速...

Vincent-Duan
昨天
60
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部