一起笨笨的学C——012数据块读写

目录

前言

正文

fread与fwrite简介:

原型及使用:

两个函数的特点:

    fread代码:

fwrite代码:

 

  后语


 

前言

        神兽中的怪兽读写专用函数:fread()和fwrite()

         阅读此篇需要有上一篇的基础:一起笨笨的学C——011文件基操-CSDN博客      


正文

fread与fwrite简介:

fgetc、fputc,一口一个字符;

fgets、fputs,一口一行字符;

fread、fwrite,一口一块字符。

哪种数据有块的概念?没错,结构体!只要建立,就在内存中暴力的占领一块区域(好像被我描述的很残暴)。fread、fwrite因为它们应运而生。

 

原型及使用:

fread()原型:

#include <stdio.h>
size_t fread(const coid *ptr, //size_t即unsigned long
size_t size, size_t count, FILE *stream);

应用举例: fread(&stud, sizeof(struct STUDENT), count, fp);

fwrite()原型:

#include <stdio.h>
size_t fwrite(const coid *ptr, //size_t=unsigned long
size_t size, size_t count, FILE *stream);

  使用举例:fwrite(&stud, sizeof(struct STUDENT), count, fp);

 

两个函数的特点:

  1. 在文件与结构体变量之间读写数据时,通常count都取1,即一块一块的读取。
  2. fread与fwrite只能以二进制的形式打开文件,所以打开i方式中要有b。
  3. 文件不加后缀就是二进制文件。
  4. fread与fwrite一起使用时,最好单独用完其中一个就关闭,再用另一个。即fopen、freadfclose或者fopenfwritefclose这样。
  5. fread的返回值是实际读取的“块数”count。如果读到文件末尾或发生错误则返回比count小的数或返回0,总之不等于count。所以与fgetc、fgets一样,要用fread的返回值和feof的返回值配合判断是否读到文件末尾。

 

    fread代码:

#include <stdio.h>
#include "dbg.h"

struct Student{
	char name[20];
	int age;
	char sex;
	char num[20];
};
//void Read(FILE *,struct Student *);

int main(int argc, char *argv[])
{
	int i ;
	int count;
	FILE *fp= fopen("stu_list", "rb");
	struct Student buf[100];
//	check((fp = fopen("stu_list", "rb")) != NULL, "Can't open the fail!");
	fseek(fp, 0, 2);
	count = ftell(fp);
	count = ftell(fp)/sizeof(struct Student);//用了ftell加fseek组合就不用判断是否读到文件末尾了,因为已经知道有多少数据,可以精确读取了。

	fseek(fp, 0, 0);
	for (i=0; i<count; ++i){
		fread(&buf[i], sizeof(struct Student), 1, fp);//此处&buf[i]也可以写作buf+i,把数组首地址当做指针用
	}

	for (i=0; i<count; ++i){
		printf("姓名: %s, 年龄: %d, 性别: %c, 学号:%s\n", buf[i].name, buf[i].age, buf[i].sex, buf[i].num);
	}
	fclose(fp);
	return 0;
}
/*
error:
	return -1;
}

xxvoid Read(FILE *fp, struct Student *p)
{
}
*/

fwrite代码:

#include <stdio.h>
#include "dbg.h"

struct Student
{
	char name[20];
	int age;
	char  sex;
	char num[20];
}
;

int main(int argc, char *argv[])
{
	int i;
	int cnt;//xuesheng de number
	FILE *fp;
	struct Student stud[10];
	
	printf("How many students do you want to input?");
	scanf("%d", &cnt);
	check((fp = fopen("stu_list", "wb")) != NULL,"Can't open the file");
	printf("Please input the name, age, sex, number:\n");
	for (i=0; i<cnt; ++i)
	{
		scanf("%s%d %c%s", stud[i].name, &stud[i].age, &stud[i].sex, stud[i].num);
		check(fwrite(&stud[i], sizeof(struct Student), 1, fp) ==1, "FIle write erro");
	}
	fclose(fp);
	return 0;
	error:
	return -1;
}

 


  后语

  1. 本章中还讲了用fread与fwrite删除文件中的数据块。它们主要针对链表,而链表还在好几个习题之后,虽然我也能弄懂,但是还是按照”笨办法“这本书架构来吧。
  2. 程序设计经验摘抄:“除非迫不得已,不要使用全局变量”。在程序设计中划分模块时要求模块的“内聚性“强,与其它函数关联性弱。函数之间通过实参与形参进行联系,这样函数间的关系就会很单一,更清晰。如果用全局变量,任何一个函数都可以改变全局变量的值,这样就很难跟踪该值的变化。
  3. scanf容错处理小妙招:,scanf后面加上的那一句清空输入缓冲区,以防用户乱输入。(如果用的多,可以考虑宏缩短语句的吧!)
    printf(”a= “);
    scanf("%f", &a);
    while(getchar()! = '\n');
    
    printf("b= "):
    scanf("%f", &b);
    while(getchar() != '\n');

     

      

 

  • 13
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值