C语言文件操作

目录

前言:

文件的分类

1. 程序文件

2.数据文件

文件的使用

 文件指针

文件指针的使用

 文件的打开与关闭

文件的使用方式

示例1:

 示例2:

 文件的顺序读写

函数简介

 示例1:

示例2:

 函数简介

示例1:

 示例2:

 函数简介

示例1:

 示例2:

 函数简介:

示例1:

示例2:

 文件的随机读写

函数简介

示例:

 函数简介

示例:

 函数简介:

示例:

 文件读取结束的判定

函数简介:

函数简介:

示例(文本文件):


前言:

当我们编写某个程序时,程序中的信息存放于内存当中,当程序退出后,再次运行,又得重新输入数据,这就涉及到数据持久化的问题,我们一般数据持久化的方法有将数据存放于电脑的磁盘上,就可以做到数据的持久化。以计算机硬盘为载体储存在计算机上的信息集合即为文件,文件最主要的作用便是保存数据。

文件的分类

1. 程序文件

包括源程序文件(后缀为.c)     目标文件(windows环境后缀.obj)

可执行程序文件(windows环境后缀为.exe)

2.数据文件

存储程序运行时读写的数据的文件,本篇只讨论数据文件

文件的使用

文件的操作一般由三步组成:

1. 打开文件        2. 读文件/写文件     3. 关闭文件

注: c语言程序运行时,默认打开标准输入流(stdin),    标准输出流(stdout)  ,     标准错误流( stderr);

 文件指针

每个被使用的文件,都在内存中开辟了一块相应的文件信息区,用来存放文件的相关信息(例如文件名 文件状态  文件当前的位置),这些信息保存到一个结构体变量中,该结构体由系统申明,取名为FILE。

struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
        };
typedef struct _iobuf FILE;

文件指针的使用

每当打开一个文件时,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,一般都是通过一个FILE的指针来维护FILE结构的变量,每次打开文件时,系统会将文件指针放在文件的开头。

  FILE* pf;//pf为文件指针变量
  //pf指向某个文件的文件信息区,通过文件信息区可以访问该文件
  //即通过文件指针变量能够找到与之关联的文件

 文件的打开与关闭

ANSIC规定使用fopen()函数打开文件,使用fclose()函数关闭文件

函数功能:当使用fopen()打开某个文件,若文件打开成功,系统主动创立文件信息区,同时返回文件信息区的起始地址;若文件打开失败,返回NULL;

参数解读:

const char* filename 打开文件的文件名   const char* mode 打开文件的方式,常用的打开方式有 "r"(只读) "w"(只写)  "a"(追加)

 函数功能:fclose()函数用来关闭当前文件流,文件成功关闭,返回0;文件关闭失败,返回  EOF;

tips: 使用fclose()函数关闭文件,还应该释放文件指针

文件的使用方式

以"w"的方式打开文件,若文件存在,会将文件的内容进行销毁,若文件不存在,建立一个新的文件;

示例1:
# include <stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "r");
	//判断打开文件是否成功
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//文件打开成功,以只读的方式使用


	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

 示例2:
int main()
{
     //在桌面上创建test.txt需要绝对路径下的文本文件名,并且为防止转义字符加上\

	FILE* pf = fopen("C:\\Users\\Administrator\\Desktop\\test.txt", "w");
	//判断打开文件是否成功
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//文件打开成功,以只写的方式使用


	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

 文件的顺序读写

函数简介

函数功能:从指定的文件流中读取一个字符,读取成功返回读取到字符的ASCII码值,读取到文件末尾或读取失败返回EOF

函数功能:向指定的文件写入一个字符,character为要写入的字符,stream为文件指针,写入成功时返回字符的ASCII码值,写入失败时返回EOF

 示例1:
# include <stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "w");
	//判断打开文件是否成功
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//文件打开成功,写文件
	fputc('a', pf);
	fputc('b', pf);
	fputc('c', pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

结果阐述:

1.文件内部有一个位置指针,用来指向当前读写到的位置,也就是读写到第几个字节;

2.当文件打开时,位置指针总是指向文件的第一个字节,每写入一个字符,文件内部的位置3指针向后移动一个字节;

3.位置指针只是一个标志,表示文件读写到的位置,并不表示地址,由系统自动设置,对用户隐藏;

示例2:
int main()
{
	FILE* pf = fopen("test.txt", "r");
	//判断打开文件是否成功
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//文件打开成功,读文件
	int ch=fgetc(pf);
	printf("%c\n", ch);
    ch = fgetc(pf);
	printf("%c\n", ch);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

 运行结果:

 函数简介

 函数功能:从stream流中读取num-1个字符存储到字符指针变量str所指向的内存空间,遇到EOF或者'\n'停止读取,并且会将'\n'也一并读取到str所对应的缓冲区中,读取成功返回str的地址,读取失败返回NULL

当num小于字符串长度时,字符串将会被截取

当num大于字符串长度时,多余部分自动用'\0' 填充

num由num-1个字符加上'\n'组成,即最后一个字符自动加上换行符;

 函数功能:

将str中的字符串写入到stream流中,但不包括'\0' ,写入成功返回大于0的数,写入失败返会EOF

示例1:
int main()
{
	FILE* pf = fopen("test.txt", "w");
	//判断打开文件是否成功
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//文件打开成功,写文件 - 写一行
	//fputs()函数只负责写入一行,并不会自动换行
	fputs("abcdef\n", pf);
	fputs("b\0it", pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

 示例2:

int main()
{
	FILE* pf = fopen("test.txt", "r");
	//判断打开文件是否成功
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//文件打开成功,读文件 - 读一行
	char arr[10] = { 0 };
	fgets(arr, 10, pf);
	printf("%s\n", arr);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

 函数简介

 函数功能:

根据数据格式const char* format,从流中读取数据存储到 [...] 的参数中;即从流中读取格式化数据;返回值有三种情况,分别为正整数,0,EOF;如果读取成功,返回实际读取的参数个数;如果读取失败,返回0;如果遇到文件末尾或读取格式错误的情况下,返回EOF;

 函数功能:

scanf第一个参数为输入格式控制符,scanf的后续参数是格式转换完成后,数据的存储位置

如果scanf将转换后的二进制存储到基本变量中,变量名前加&操作符;

如果scanf()函数将字符串存储到字符数组中,字符数组名不用加&操作符;

 函数功能:

函数第一个参数为存储数据的位置,第二个参数为格式控制字符串,sscanf函数会从s里读取数据,依照format的格式将数据写入到 [...]数据的存储位置;即将字符串转换为具有一定格式的数据;

结论:

scanf函数从标准输入流(stdin)中读取数据,而fscanf函数适用于所有输入流,可以将数据从自定义的流(stream)中读取出来,不仅仅局限于标准输入流

函数功能:

fprintf函数根据指定的格式(format) ,向输出流(stream)写入数据[...],fprintf()函数的返回值为打印的字符的个数;

 函数功能:

向标准输出设备按规定格式输出信息

函数功能:

将具有一定格式的数据转换为字符串;

结论:printf函数打印数据到标准输出流(stdout),而fprintf()函数适用于所有输出流,可以将数据写到自定义的流中,不仅仅局限于标准输出流;

示例1:
struct s
{
	int a;
	float b;
};
int main()
{
	FILE* pf = fopen("test.txt", "w");
	//判断打开文件是否成功
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//文件打开成功,写文件
	struct s s1 = { 100, 3.14f };
	fprintf(pf, "%d %f", s1.a, s1.b);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

 示例2:
struct s
{
	int a;
	float b;
};
int main()
{
	FILE* pf = fopen("test.txt", "r");
	//判断打开文件是否成功
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//文件打开成功,读文件
	struct s s1 = { 0 };
	fscanf(pf, "%d %f", &(s1.a), &(s1.b));
	printf("%d %f", s1.a, s1.b);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

 函数简介:

 函数功能:

从文件中读取若干个字节数据到内存的缓冲区中

void* ptr:将文件中的二进制数据读取到该缓冲区中;

size_t size:读取的基本单元的大小,单位是字节,一般为ptr缓冲单位大小;

  • 如果ptr缓冲区是char类型数组,则该参数的值是sizeof(char)
  • 如果ptr缓冲区是int类型数组,则该参数的值是sizeof(int)

size_t count :读取的基本单元的个数

FILE* stream : 文件指针

fread函数的返回值为实际从文件中读取的 基本单元的个数;读取的字节数=基本单元数*基本单元字节的大小;

 函数功能:

const void *ptr : 指针指向的数据的内存首地址 ;数据来自ptr

size_t size : 要写出数据的 基本单元 的字节大小 , 写出单位的大小 ;

size_t count : 要写出数据的 基本单元 的个数 ;

FILE *stream : 打开的文件指针 ;

返回值为实际写入到文件的基本单元的个数

示例1:
struct S
{
	int a;
	float b;
	char arr[10];
};
int main()
{
	struct S s1 = { 100, 3.14f, "abc" };
	//以二进制写入的形式打开文件
	FILE* pf = fopen("data.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	fwrite(&s1, sizeof(struct S), 1, pf);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果(二进制文件):

示例2:
struct S
{
	int a;
	float b;
	char arr[10];
};
int main()
{
	struct S s1 = { 0 };
	//以二进制读取的形式打开文件
	FILE* pf = fopen("data.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	fread(&s1, sizeof(struct S), 1, pf);
	printf("%d %f %s\n", s1.a, s1.b, s1.arr);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

 文件的随机读写

文件的随机读写指的是从指定的位置进行读写操作;

函数简介

函数功能:

fseek函数设置文件指针stream的位置,如果执行成功,文件指针将指向以origin为基准,偏移offset个字节的位置;若执行失败,则不改变stream指向的位置;当文件指针定位成功时返回0,否则返回其他值;

第一个参数为文件指针

第二个参数offset为偏移量,正数表示正向偏移,负数表示负向偏移

第三个参数origin设定从文件的那个位置开始偏移,c语言规定起始位置有3种,分别为文件开头,当前位置,文件末尾;

起始点常量名常量值
文件开头SEEK_SET0
当前位置SEEK_CUR1
文件末尾SEEK_END2

 注:每使用完一次 fseek函数,文件指针自动向后移动一位

示例:

int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	//定位文件指针到f的位置
	fseek(pf, 5, SEEK_SET);
	int ch = fgetc(pf);
	printf("%c\n", ch);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

 运行结果:

 函数简介

函数功能:

获取文件的 当前指针位置 相对于 文件起始地址的偏移字节数

示例:

int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	//定位文件指针到f的位置
	int ch = fgetc(pf);
	printf("%c\n", ch);//a

	 ch = fgetc(pf);
	printf("%c\n", ch);//b

	 ch = fgetc(pf);
	printf("%c\n", ch);//c

	int pos = ftell(pf);
	printf("%d\n", pos);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

 函数简介:

 函数功能:

将文件内部的位置指针重新指向一个流(数据流/ 文件流)的起始位置

示例:
int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	//定位文件指针到f的位置
	int ch = fgetc(pf);
	printf("%c\n", ch);//a

	 ch = fgetc(pf);
	printf("%c\n", ch);//b

	rewind(pf);//让文件内部的位置指针回到起始位置
	ch = fgetc(pf);
	printf("%c\n", ch);//a

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

 文件读取结束的判定

函数简介:

 函数功能:

当文件读取结束时,判断读取结束的原因是否是遇到文件末尾结束;没有到达文件末尾,返回0;到达文件末尾,返回非0值;

注:在文件读取的过程中,不能使用feof函数的返回值判断文件是否读取结束;

那么如何判断一个文件读取结束呢?

1. 文本文件读取是否结束,判断返回值是否为EOF或者NULL

  • fgetc判断是否为EOF
  • fgets判断返回值是否为NULL

2. 二进制文件的读取结束判断返回值是否小于实际要读的个数

  •  fread判断返回值是否小于要读的个数;
函数简介:

 函数功能:

当文件读取结束时,判断是否遇到错误读取结束,无错误出现时返回0,有错误出现时返回非0;

示例(文本文件):
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("File opening failed");
		return 1;
	}
	//fgetc当读取失败或者遇到文件结束时,都会返回EOF
	int c;
	while ((c = fgetc(pf)) != EOF)
	{
		putchar(c);//正常读取
	}
	printf("\n");
	//读取结束
	//判断什么原因读取结束
	if (ferror(pf))
	{
		printf("I/O error when reading\n");
	}
	else if (feof(pf))
	{
		printf("End of File reached successfully\n");
	}
	return 0;
}

运行结果:

  • 30
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小呆瓜历险记

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

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

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

打赏作者

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

抵扣说明:

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

余额充值