【C语言】文件操作(附源码与图片)

文件操作管理

  • 1、文件打开
  • 2、文件的顺序读写
    • 2.1fputc函数
    • 2.2fgetc函数
    • 2.3fgets函数
    • 2.4fputs函数
    • 2.5fprintf函数
    • 2.6fcanf函数
    • 2.7sprintf函数与sscanf函数
    • 2.8print与scanf大家族
    • 2.9fwrite函数
    • 2.10fread函数
  • 3、文件的随机读写
    • 3.1fseek函数
    • 3.2ftell函数
    • 3.3rewind
  • 4、文件读取结束的判定
    • 4.1被错误使用的feof
  • 5、多文件复制

1、文件打开


  • 文件在读写之前应该先打开文件 ,再使用结束之后应该关闭文件*。
  • 编写程序时打开文件,都会返回应该FILE*的指针变量指向该文件,相当于建立了指针和文件的关系。
  • 使用fopen函数来打开文件,fclose来关闭文件。
C 复制代码
//打开文件
FILE * fopen("文件名","模式");

//关闭文件
int fclose(fopen);
文件使用方式 含义 如果指定文件不存在
"r"(只读) 为了输入数据,打开已经存在的文本文件 出错
"w"(只写) 为了输出数据,打开应该文本文件 建立一个新的文件
"a"(追加) 向文本问及那尾添加数据 建立一个新的文件
"rb"(只读) 为了输入数据,打开应该二进制文件 出错
"wb"(只写) 为了输出数据,打开应该二进制文件 建立一个新的文件
ab"(追加) 向一个二进制文件尾添加数据 建立一个新的文件
"r+"(读写) 为了读和写,打开一个文本文件 出错
w+"(读写) 为了读和写,建立⼀个新的文件 建立一个新的文件
"a+"(读写) 打开一个文件,在文件尾进行读写 建立一个新的文件
"rb+"(读写) 为了读和写打开一个二进制文件 出错
wb+"(读写) 为了读和写,新建一个新的二进制文件 建立一个新的文件
"ab+"(读写) 打开⼀个二进制文件,在文件尾进行读和写 建立一个新的文件
C 复制代码
/* test.txt */
#include<stdio.h>
int main()
{
	//打开文件
	FILE *ps = ("test.txt", "w");
	//文件操作
	if(ps ! = NULL)
	{
		//写文件
		fputs("a", ps);
		//关闭文件
		fclose(ps);
	}
	return 0;
}

2、文件的顺序读写


函数名 功能 适用于
fgetc 字符输入函数 所有输入流
fputc 字符输出函数 所有输入流
fgets 文本行输入函数 所有输入流
fputs 文本行输出函数 所有输入流
fscanf 格式化输入函数 所有输入流
fprintf 格式化输出函数 所有输入流
fread 二进制输入 文件输入流
fwrite 二进制输出 文件输入流

上面说的适用于所有输入流一般只适用于标准输入流和其他输入流(如文件输入流);所有输出流一般适用于标准输出流和其他输出流(如文件输出流)

2.1fputc函数


C 复制代码
int fgetc ( FILE * stream );
C 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	//打开文件(存在的情况下)
	FILE* ps = fopen("test.txt", "w");
	if (ps == NULL)
	{
		perror("fopen");
		return 1;
	}

	int ch = 0;
	for (ch = 'a'; ch <= 'z'; ch++)
	{
		//输入字符
		fputc(ch, ps);
	}

	//关闭文件
	fclose(ps);
	return 0;
}

此时的test.txt文件
abcdefghijklnmopqrstuvwxyz

2.2fgetc函数


test.txt文件
abcdefghizklmnopqrstuvwxyz

C 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	//打开文件(存在的情况下)
	FILE* ps = fopen("test.txt", "r");
	if (ps == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件
	int ch = 0;
	while ((ch = fgetc(ps)) != EOF)
	{
		printf("%c", ch);
	}

	//关闭文件
	fclose(ps);
	return 0;
}

屏幕上显示:abcdefghizklmnopqrstuvwxyz

2.3fgets函数


  • 当num为10时,第10个会放\0
  • 当数组过短,num过大时,会在数组后补上\n,后补\0
  • fgets读取方式是一行一行的读
C 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	//打开文件
	FILE* ps = fopen("test.txt", "r");
	if (ps == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件
	char arr[10] = { 0 };
	//最多读19个,再继续往后读,直到遇到\0再换行
	while (fgets(arr, 20, ps) != NULL)
	{
		fgets(arr, 10, ps);
	}

	//关闭文件
	fclose(ps);
	ps = NULL;

	return 0;
}

2.4fputs函数


C 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	//打开文件
	FILE* ps = fopen("test.txt", "w");
	if (ps == NULL)
	{
		perror("fopen");
		return 1;
	}

	//写文件
	fputs("hello world\n", ps);
	fputs("hello bit\n", ps);

	//关闭文件
	fclose(ps);
	ps = NULL;

	return 0;
}

也可以打印到屏幕上,用stdout输出流

C 复制代码
fputc('a', stdout);

2.5fprintf函数


C 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

struct Stu
{
	char name[20];
	int age;
	float score;
};

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	
	//写入
	struct Stu s = { "张三",20,66.0 };
	fprintf(pf, "%s %d %f", s.name, s.age, s.score);

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

test.txt文件中显示:

复制代码
张三 20 66.0

也可以打印在屏幕上,只需要用stdout输出流即可

C 复制代码
fprintf(stdout, "%s %d %f", s.name, s.age, s.score);

屏幕上打印为:

复制代码
张三 20 66.0

2.6fcanf函数


前面test.txt文本建立时,将文本里的数据拿出时,要用到fcanf来读取

C 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

struct Stu
{
	char name[20];
	int age;
	float score;
};

int main()
{
	struct Stu s = { 0 };
	//想从文件test.txt中读取数据放在s中
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件
	fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));

	//打印在屏幕上
	printf("%s %d %f", s.name, s.age, s.score);

	fclose(pf);
	pf = NULL;
	return 0;
}

2.7sprintf函数与sscanf函数


C 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

struct Stu
{
	char name[20];
	int age;
	float score;
};

int main()
{
	char buf[200] = { 0 };
	struct Stu s = { "张三", 20, 65.5f };
	//转化成字符串
	sprintf(buf, "%s %d %f", s.name, s.age, s.score);
	//以字符串的形式打印
	printf("1以字符串的形式:%s\n", buf); //1


	struct Stu t = { 0 };
	//读取buf字符串中的格式化的数据
	sscanf(buf, "%s %d %f", t.name, &(t.age), &(t.score));
	//以格式化形式打印
	printf("2以格式化打印:%s %d %f\n", t.name, t.age, t.score); //2

	return 0;
}

2.8print与scanf大家族


2.9fwrite函数


C 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

struct Stu
{
	char name[20];
	int age;
	float score;
};

int main()
{
	int arr[5] = { 0 };
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//写数据
	int sz = sizeof(arr) / sizeof(arr[0]);
	fwrite(arr, sizeof(arr[0]), sz, pf);

	fclose(pf);
	pf = NULL;

	return 0;
}

打印出乱码

2.10fread函数


C 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

struct Stu
{
	char name[20];
	int age;
	float score;
};

int main()
{
	int arr[5] = { 0 };
	FILE* pf = fopen("test.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读数据
	fread(arr, sizeof(arr[0]), 5, pf);
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", arr[i]);
	}

	fclose(pf);
	pf = NULL;

	return 0;
}

打印的结果为:

复制代码
0 0 0 0 0

3、文件的随机读写


3.1fseek函数

根据文件指针的位置和偏移量来定位文件指针(文件内容的光标)!

test.txt文件abcdefg

C 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件,移动4个字节,(SEEK_CUP)从起始位置开始
	fseek(pf, 4, SEEK_CUR);
	int ch = 0;
	ch = fgetc(pf);
	printf("%c", ch);

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

打印的结果为:e

3.2ftell函数


返回文件指针相对于起始位置的偏移量

test.txt文件abcdefg

C 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件,移动4个字节,(SEEK_CUP)从起始位置开始
	fseek(pf, 4, SEEK_CUR);
	int ch = 0;
	ch = fgetc(pf);
	printf("%c\n", ch);
	//偏移量
	printf("%d\n", ftell(pf));

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

打印的结果为:

复制代码
e
5

3.3rewind


让文件指针的位置回到文件的起始位置

test.txt文件abcdefg

C 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件,移动4个字节,(SEEK_CUP)从起始位置开始
	fseek(pf, 4, SEEK_CUR);
	int ch = 0;
	ch = fgetc(pf);
	printf("%c\n", ch);

	//偏移量
	printf("%d\n", ftell(pf));//e

	//起始位移量
	rewind(pf);//5

	//读文件
	ch = fgetc(pf);
	printf("%c\n", ch);//a

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

4、文件读取结束的判定

4.1被错误使用的feof


牢记 :在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否接受。
feof的作用是:当文件读取结束的时候,判断读取结束的元素是否是:遇到文件尾结束。

  1. 文本文件读取是否结束,判断返回值是否为EOF(fgetc),或者NULL(fgets
    )
    fgetc函数:
  • 如果读取正常,返回的是读取到字符的ASCLL码值
  • 如果读取的过程中遇到文件末尾,或者发生错误,就返回EOF

fgets函数:

  • 如果读取正常,返回的是存储读取到的字符串的字符数组的地址
  • 如果读取的过程中遇到文件末尾,或者发生错误,返回NULL
  1. 二进制文件的读取结束判断,判断返回值是否小于世界要读的个数。
  • fread判断返回值是否小于实际要读的个数
C 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件
	int ch = 0;
	while ((ch = fgetc(pf)) != EOF)
	{
		printf("%c\n", ch);
	}

	//判断是什么原因导致读取结束的
	if (feof(pf))
	{
		printf("文件遇到末尾,读取正常结束\n");
	}
	else if (ferror(pf))
	{
		perror("fgetc");
	}
	
	//关闭文件
	fclose(pf);
	pf = NULL;
	
	return 0;
}

5、多文件复制


我们要把一个文件拷贝给另一个文件,可以用到上面学过的知识

C 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
	FILE* pin = fopen("test.txt", "r");
	if (pin == NULL)
	{
		perror("fopen");
		return 1;
	}

	FILE* pout = fopen("test2.txt", "w");
	if (pout == NULL)
	{
		fclose(pin);
		pin = NULL;
		return 1;
	}

	int ch = 0;
	while ((ch = fgetc(pin)) != EOF)
	{
		fputc(ch, pout);
	}

	fclose(pin);
	fclose(pout);
	pin = NULL;
	pout = NULL;

	return 0;
}
相关推荐
码事漫谈19 分钟前
智能体颠覆教育行业调研报告:英语、编程、语文、数学学科应用分析
后端
蓝-萧22 分钟前
使用Docker构建Node.js应用的详细指南
java·后端
码事漫谈1 小时前
《C语言点滴》——笑着入门,扎实成长
后端
Tony Bai1 小时前
【Go模块构建与依赖管理】09 企业级实践:私有仓库与私有 Proxy
开发语言·后端·golang
杨福瑞2 小时前
数据结构:单链表(2)
c语言·开发语言·数据结构
咖啡教室2 小时前
每日一个计算机小知识:ICMP
后端·网络协议
间彧2 小时前
OpenStack在混合云架构中通常扮演什么角色?
后端
咖啡教室2 小时前
每日一个计算机小知识:IGMP
后端·网络协议
间彧2 小时前
云原生技术栈中的核心组件(如Kubernetes、Docker)具体是如何协同工作的?
后端
清空mega2 小时前
从零开始搭建 flask 博客实验(3)
后端·python·flask