文件读写操作

Tips

1、读、写缓冲区:提升读写速度,提高硬盘寿命(避免频繁读写硬盘);

2、EOF: End Of File,文件结束标识。

文件打开方式

方式

描述

r

只读。

文件必须已经存在

w

只写。

如果文件不存在,则新创建一个文件。会从新创建的文件开头写。

如果文件已经存在,则会被截断为0长度,重新写入。

a

追加模式写。

如果文件不存在,则会新创建一个文件。

在已有的文件内容之后追加写。

r+

读和写。

文件必须已存在。

w+

读和写。

如果文件不存在,则新建文件。

如果文件已存在,则会被截断为0长度,重新写入。

a+

读和写。

如果文件不存在,则新创建一个文件。

读:从文件开头开始读。

写:在文件尾追加写。

Tips

如果处理的是二进制文件,则需使用如下对应的文件打开方式。(b:binary,二进制)。

“rb”、“wb”、“ab”、“rb+”、“wb+”、“w+b”、“ab+”、“a+b”。

文件读写函数
打开文件
创建一个新的文件,或者打开一个已经存在的文件。
FILE *fopen( const char * filename, const char * mode );
关闭文件
int fclose( FILE *fp );
如果关闭成功,则返回0;如果关闭失败,则返回EOF。fclose有两个作用:
1、将缓冲区中的内容写入文件,防止缓冲区内容丢失;
2、释放用于该文件的内存,防止内存泄漏。

读写文件
按照字符读写: fgetc()、fputc()
eg:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 按字符读写文件fputc\fgetc
void test1()
{
    // 按照字符写
    FILE *f_write = fopen("./rw_by_ch.txt", "w");
	if (f_write == NULL) {
        return;
	}
	char buff[] = "read/witer file test by ch";
	for (unsigned int i = 0; i < strlen(buff); i++) {
        fputc(buff[i], f_write);
	}
	fclose(f_write);

	// 按照字符读
	FILE *f_read = fopen("./rw_by_ch.txt", "r");
	if (f_write == NULL) {
        return;
	}
	char ch;
	while((ch = fgetc(f_read)) != EOF) { //EOF:End Of File
	    printf("%c", ch);
	}
	printf("\n");
	fclose(f_read);
}

int main()
{
    test1();
    system("pause");
	return 0;
}

 
按照行读写:fputs()、fgets()
// 2、按行读写文件:fputs、fgets
void test2()
{
	int len;
	char temp[1024] = { 0 };
	char *buf[] = {
	    "锄禾日当午\n",
		"汗滴禾下土\n",
		"谁知盘中餐\n",
		"粒粒皆辛苦\n",
	};
	// 写文件
    FILE *f_write = fopen("./test2.txt", "w+");
	if (f_write == NULL) {
	    return;
	}
	int len = (sizeof(buf) / sizeof(char *)); //len = 4; 指针数组:指针占4B
	printf("len %d\n", len);
	for (int i = 0; i < len; i++) {
	    fputs(buf[i], f_write);
	}
	fclose(f_write);
    // 读文件
    FILE *f_read = fopen("./test2.txt", "r");
	if (f_read == NULL) {
	    return;
	}
	while (!feof(f_read)) { // feof:判断是否读到文件结尾
		memset(temp, 0, 1024);
	    fgets(temp, 1024, f_read);
		printf("%s", temp);
	}
	fclose(f_read);
	return;
}

 
按照块读写: fwrite()、fread()
// 按照块读写
typedef struct _Hero
{
   char name[20];
   int age;
}HERO_S;


void test3()
{
    FILE *f_write = fopen("./rw_by_block.txt", "wb");
	if (f_write == NULL) {
		return;
	}
	HERO_S heros[4] = {
		{"孙悟空", 500},
		{"曹操", 80},
		{"吕布", 60},
		{"奥特曼", 100}
	};
	// 写方法:循环写,每次写一块
	//for(int i = 0; i < 4; i++) {
	//    fwrite(&heros[i], sizeof(heros[i]), 1, f_write);
	//}
	// 写方法:一次写块
      fwrite(&heros, sizeof(HERO_S), 4, f_write);  // 写
	fclose(f_write);

	FILE *f_read = fopen("./rw_by_block.txt", "rb");
	if (f_read == NULL) {
		return;
	}
    
	HERO_S tmpBuf[4];
	fread(&tmpBuf, sizeof(HERO_S), 4, f_read); // 读
	for (int i = 0; i < 4; i++) {
		printf("Name:%s \t Age:%d\n", tmpBuf[i].name, tmpBuf[i].age);
	}
	printf("\n");
    fclose(f_read);
}

按照格式化读写: fscanf()、fsprint()
// 按格式读写 -----------------------------------------------------------------
void test4()
{
    FILE *f_write = fopen("./rw_by_format.txt", "w");
	if (f_write == NULL) {
	    return;
	}
	// fprintf(f_write, "write by format %s\n", "file test");
	fprintf(f_write, "write by format");
    fclose(f_write);

	FILE *f_read = fopen("./rw_by_format.txt", "r");
	if (f_read == NULL) {
	    return;
	}
	char temp[1024] = { 0 };
	while(!feof(f_read)) {
	    fscanf(f_read, "%s\n", temp);
		printf("%s\n", temp);
	}
	printf("\n");
	fclose(f_read);
}

按照随机位置读写: fseek()、ftell()、rewind()
// 随机位置读写 -----------------------------------------------------------------
void test5()
{
    FILE *f_write = fopen("./rw_by_rand.txt", "wb");
	if (f_write == NULL) {
        perror("文件打开失败"); // perror:打印用户指定信息+ 系统调试信息,eg:文件打开失败:指定文件或路径不存在
		return;
	}
	HERO_S heros[4] = {
		{"孙悟空", 500},
		{"曹操", 80},
		{"吕布", 60},
		{"奥特曼", 100}
	};
    fwrite(&heros, sizeof(HERO_S), 4, f_write);
	fclose(f_write);

	HERO_S tmp;
	FILE *f_read = fopen("./rw_by_rand.txt", "rb");
	if (f_read == NULL) {
		return;
	}
	// argc1:文件指针;argc2:偏移量;argc3:起始位置--SEEK_SET:文件开头,SEEK_CUR:当前位置,SEEK_END:文件结尾
	//fseek(f_read, sizeof(HERO_S) * 2, SEEK_SET); //SEEK_SET:从文件开头,偏移两个结构变量,读
      //SEEK_END:从文件结尾偏移(负的)两个结构变量,读;因为sizeof返回值为unsigned int,所以需要先强转成long
	fseek(f_read, -(long)sizeof(HERO_S) * 3, SEEK_END);    
fread(&tmp, sizeof(HERO_S), 1, f_read);
	rewind(f_read); // 将文件光标置首
	printf("姓名:%s, 年龄: %d\n", tmp.name, tmp.age);
    fclose(f_read);
}

注意事项

1、按照字符方式读写时,通常利用EOF来判断是否到文件结尾。

如下所示:

因为feof具有“滞后性”,如果要用feof来判断,则需要加上如下判断。

2、自定义数据类型写文件时,不要将指针写入到文件里

因为指针指向的内容可能随时会变。所以需要将指针指向的内容写入文件。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值