C语言基础(九)----文件操作



来源:微信公众号「编程学习基地」

文件操作

程序运行产生的数据是存储在内存中的,当程序关闭的时候,数据随之丢失,想要保存数据,需要进行文件操作将数据保存在磁盘中。

缓冲区

在进行文件操作的时候,为了提高存取效率,程序在执行是会提供额外的内存暂时存放数据,这块内存就是缓冲区

例如写入文件时:

FILE*fWrite;
if (!(fWrite = fopen("test.txt", "w")))
{
	printf("file was not opened! ");
	exit(1);
}
fputc('a');

在这里字符a只是写入到了缓冲区,并没有写入磁盘。当你关闭文件或者缓冲区已满的时候才会写入到磁盘当中,例如进行文件关闭代码:

fclose(fWrite);
文件类型
  • 文本文件:例如.txt 、.c 、.cpp文件,人能够看懂
  • 二进制文件:以二进制形式写入的文件,除了文本文件外,所有的数据都可以算是二进制文件
路径
  • 绝对路径

右键任意文件,点击属性,在位置那一栏里面可以找到该文件的绝对路径

注意!!!注意!!!注意!!!

D:\test 	D盘下的text文件夹
文件读取时要换成:
D:\\test\\test.txt	两个\\是因为:单独一个\是转义,两个\\才代表'\'
或者
D:/test/test.txt	用这个是为了区分转义字符
  • 相对路径

相对路径是相对于工作空间而言的,在windows和Linux下

…/ 表示上级目录

./ 表示当前目录

fWrite = fopen("./test.txt", "w"));		//表示当前文件夹下的test.txt文件 ./可忽略
fWrite = fopen("../test.txt", "w"));	//表示当前文件的上级目录下的test.txt文件

在程序打包过程中,如果出现程序运行什么都没有,一般是路径弄错了,导致程序找不到图片资源。

程序中一般用的是相对路径寻找文件

文件操作函数

打开关闭文件
FILE*fWrite, *fRead;
//第一种打开文件的方法
if (!(fWrite = fopen("test.txt", "w")))
{
	printf("file was not opened! ");
	exit(1);
}
//第二种打开文件的方法
fRead = fopen("test.txt", "r");
if (fRead == NULL)
{
	printf("file was not opened! ");
	exit(1);
}

需要注意的是:

  • 文件的打开方式
"t":表示文本文件    rt  一般t可以省略不写
"b":表示二进制文件  rb  
"+":表示文件可读写

"r":只能从文件中读数据,该文件必须先存在,否则打开失败
"w":只能向文件写数据,若指定的文件不存在则创建它,如果存在则先删除它再重建一个新文件
"a":向文件增加新数据(不删除原有数据),若文件不存在则打开失败,打开时位置指针移到文件末尾
"r+":可读/写数据,该文件必须先存在,否则打开失败
"w+":可读/写数据,用该模式打开新建一个文件,先向该文件写数据,然后可读取该文件中的数据
"a+":可读/写数据,原来的文件不被删去,位置指针移到文件末尾
  • 打开文件之后要判断下是否打开成功
  • 记得关闭文件
fclose(fRead);
fclose(fWrite);
字符读写函数 fgetc / fputc

函数原型:

int fputc(
int c,		 //字符
FILE *stream //文件指针
);
int fgetc(
FILE *stream //文件指针
);

程序示例:

void function()
{
    //打开文件
	FILE*fWrite, *fRead;
	if (!(fWrite = fopen("./test.txt", "w")))
	{
		printf("file was not opened! ");
		exit(1);
	}
	fRead = fopen("./test.txt", "r");
	if (fRead == NULL)
	{
		printf("file was not opened! ");
		exit(1);
	}
	/*************** fputc *****************/
    //写入单个字符
	fputc('a', fWrite);	//写入字符
	//循环写入字符
    char arr[128] = "你好,世界!";
	//for (int i = 0; i < strlen(arr); i++)
	//{
	//	fputc(arr[i], fWrite);
	//}
    char *p = arr;
	while ((*p != '\0') && fputc(*(p++), fWrite) != EOF);
	fclose(fWrite);	//一定要记得关闭文件
	/*************** fgetc *****************/
    //单个读取字符
	char ch = fgetc(fRead);
	putchar(ch);
    
	rewind(fRead);	//将文件内部指针移回文件开头
	//循环读取字符
	//for (int i = 0; (ch = fgetc(fRead)) != EOF; i++)
	//{
	//	arr[i] = ch;
	//}
    //puts(arr);
	while (!feof(fRead))	//feof函数
	{
		printf("%c", fgetc(fRead));
	}
	fclose(fRead);
}

在Linux下看到的效果更明显:

ubuntu@ubuntu:~/work$ ls
main.c  
ubuntu@ubuntu:~/work$ gcc main.c -o main.exe
ubuntu@ubuntu:~/work$ ls
main.c  main.exe  
ubuntu@ubuntu:~/work$ ./main.exe 
aa你好,世界!
ubuntu@ubuntu:~/work$ ls
main.c  main.exe  test.txt

我们可以明显的看到work/目录下在运行main.exe程序之后得到test.txt这个文件

注意:

  • 第一步是打开文件fopen,然后判断是否打开成功
  • 读写操作要分别用两个文件指针
  • 然后进行读写操作,同时对一个文件进行读写操作会出错,当写入操作完成之后再进行读取操作
  • EOF是宏定义#define EOF (-1) 文本文件的文件末尾标志
  • feof()函数是判断文件指针是否读到文件末尾,到达文件末尾返回一真值
字符串读写函数 fgets / fputs

函数原型:

int fputs(
   const char *str,	//字符数组
   FILE *stream		//文件指针
);
char *fgets(
   char *str,		//字符数组
   int numChars,	//最多读取的字符个数
   FILE *stream		//文件指针
);

示例:

//写入
fputs( "Hello world\n", fWrite);
//读取
char arr[128];
while (fgets(arr, 127, fRead) != NULL)	//arr至少留一个位置给'\0'
{
	puts(arr);
}
格式化读写文件 fprintf / fscanf

函数原型:

int fprintf(
   FILE *stream,		//文件指针
   const char *format [,//字符数组
   argument ]...
);
int fscanf(
   FILE *stream,		//文件指针
   const char *format [,//字符数组
   argument ]...
);

这两个函数和printf,scnaf类似,示例如下

	//写入文件
	fprintf(fWrite, "我的学号是%d\n",1001);
	char arr[128]="你好,世界!";
	fprintf(fWrite,arr);
	//读取文件
	while (!feof(fRead))
	{
		fscanf(fRead, arr);
		puts(arr);
	}
二进制读写文件 fread / fwrite

函数原型:

size_t fwrite(
   const void *buffer,	//指向要写入的数据的指针
   size_t size,			//要写入项目的大小,以字节为单位
   size_t count,		//要写入的最大项目数
   FILE *stream			//指向FILE结构的指针
);
size_t fread(
   void *buffer,		//数据的存储位置
   size_t size,			//项目大小(以字节为单位)
   size_t count,		//读取的最大项目数
   FILE *stream			//指向FILE结构的指针
);

在读写结构体的时候强烈推荐这种的读写方式,简单,方便

示例:

#include<stdio.h>
typedef struct student
{
	int iId;
	int iScore;
}STU;
int main()
{
    FILE*fWrite, *fRead;
	if (!(fWrite = fopen("test3.dat", "wb")))
	{
		printf("file was not opened! ");
		exit(1);
	}
	fRead = fopen("test3.dat", "rb");
	if (fRead == NULL)
	{
		printf("file was not opened! ");
		exit(1);
	}
	/*************** fwrite *****************/
	STU stu = { 1001,100 };
	fwrite(&stu			//指向要写入的数据的指针
		, sizeof(stu)	//项目大小,以字节为单位
		, 1				//要写入的最大项目数
		, fWrite		//指向FILE结构的指针
	);
	stu.iId = 1002;
	fwrite(&stu			//指向要写入的数据的指针
		, sizeof(stu)	//项目大小,以字节为单位
		, 1				//要写入的最大项目数
		, fWrite		//指向FILE结构的指针
	);
	fclose(fWrite);
	/*************** fread *****************/
	rewind(fRead);	//将文件内部指针移回文件开头
	STU temp;
	while (1)
	{
		fread(&temp			//指向要写入的数据的指针
			, sizeof(STU)	//项目大小,以字节为单位。
			, 1				//要写入的最大项目数
			, fRead			//指向FILE结构的指针
		);
		if (feof(fRead)) break;
		printf("id:%d\tscore:%d\n", temp.iId, temp.iScore);
	}
	fclose(fRead);
    return 0;
}

也可以参考下学生信息管理系统里面的读写操作

文件指针的操作

上述所有的文件操作都是顺序读写文件

  • rewind

使文件位置标志重新返回文件的开头

rewind(fRead); //相当于你接下来读取的位置为fRead指向文件的开头位置
  • fseek
int fseek(
   FILE *stream,	//指向FILE结构的指针
   long offset,		//从初始位置开始的字节数
   int origin		//初始位置
);

其中origin设置有这三个宏

原始值原值含义
SEEK_SET0文件的开头
SEEK_CUR1文件指针的当前位置
SEEK_END2文件末尾

示例:

fseek(fRead,sizeof(STU),SEEK_SET);	//将文件指针移到开始位置sizeof(STU)字节处

  • ftell
long ftell(
   FILE *stream
);

作用:得到文件标志的当前位置

示例:

long index=ftell(fRead);	//得到文件指针的位置
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeRoy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值