【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;
}
相关推荐
IT_陈寒3 小时前
Python+AI实战:用LangChain构建智能问答系统的5个核心技巧
前端·人工智能·后端
无名之辈J4 小时前
系统崩溃(OOM)
后端
码农刚子4 小时前
ASP.NET Core Blazor简介和快速入门 二(组件基础)
javascript·后端
间彧4 小时前
Java ConcurrentHashMap如何合理指定初始容量
后端
catchadmin4 小时前
PHP8.5 的新 URI 扩展
开发语言·后端·php
少妇的美梦4 小时前
Maven Profile 教程
后端·maven
白衣鸽子4 小时前
RPO 与 RTO:分布式系统容灾的双子星
后端·架构
Jagger_4 小时前
SOLID原则与设计模式关系详解
后端
秦.赢渠梁4 小时前
各种通信(三):GPS模块数据解析
c语言