C语言文件操作

有时候程序运行后会有我们要操作的数据,或是存储的数据,例如我们前面所写的 通讯录程序,我们就需要存储联系人的信息,然而在程序运行完了之后,我们的信息就都会消失,因为我们的数据都在内存上。如果我们要永久性的存储需要存在外存上。这时候就到了C语言的文件操作登场了。

目录

文件的分类

文件指针

文件基本操作

操作函数

文件名称

文件打开方式

附加

1、字符读写

2、字符串读写

文件的运用


文件的分类

文件是信息存储的基本单位。所以根据存储的方式不同可分为:

  1. 文本文件:看的懂的
  2. 二进制文件:看不懂的

文件指针

用一个指针变量指向一个文件,这个指针便是文件指针。我们通过指针对文件进行操作。

定义的方式为:

FILE*  + 指针变量名

//C语言
FILE* fp;

文件基本操作

文件只有打开了才能进行操作,当然操作完之后你必须关闭文件。 因为程序打开文件个数是有限的!如果频繁打开文件,没有关闭便会是文件描述符泄露。

  • 操作函数

  • 打开:fopen(const char* path, const char* made)

path:   文件名称       made:   打开方式

  • 读取:fread(const void* buffer, size_t size, size_t count, FILE* fp)

buffer:存放输入数据首地址     size * count:整个数组大小   fp:文件指针

  • 写入:fwrite(const void* buffer, size_t size, size_t count, FILE* fp)

buffer:存放输出数据首地址     size * count:整个数组大小   fp:文件指针

  • 关闭:fclose(FILE* fp)                               
  • 文件名称

文件名=文件目录 + 文件名

文件的打开实在源代码的路径下。

如果在源代码的路径下创建了  test.txt

./test.txt        表示当前文件夹内

../test.txt       表示上一级的文件夹内
  • 文件打开方式

文件打开方式
"r"(只读)为输入打开一个文本文件
"w"(只写)为输出打开一个文本文件
"a"(追加)向文件文件尾添加数据
"r+"(读写)为读写打开一个文本文件
"w+"(读写)为读写建立一个新的文本文件
"a+"(读写)为读写打开一个文本文件
  1. "rb"(只读) 为输入打开一个二进制文件
  2. "wb"(只写) 为输出打开一个二进制文件
  3. "rb+"(读写) 为读写打开一个二进制文件
  4. "wb+"(读写) 为读写建立一个新的二进制文件
  5. "ab+"(读写) 为读写打开一个二进制文件

 打开操作

//C语言
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>

void main() {
	FILE* fp;
	fp = fopen("./test.txt","r");
	if (fp==NULL) {
		printf("文件不存在,打开失败!\n");
	}
	else {
		printf("文件已打开!\n");
	}
	fclose(fp);
	system("pause");
}

 若文档不存在:

文件存在:

读操作

//C语言
void main() {
	FILE* fp;

	fp = fopen("./test.txt","r");
	if (fp==NULL) {
		printf("文件不存在,打开失败!\n");
	}
	else {
		printf("文件已打开!\n");
	}
	char arr[1024] = { 0 };

	fread(arr, 1, 9, fp);
	printf("%s\n", arr);
	fclose(fp);

	system("pause");
}

写操作

//C语言
void main() {
	FILE* fp;
	
	fp = fopen("./test.txt","w");
	if (fp==NULL) {
		printf("文件不存在,打开失败!\n");
	}
	else {
		printf("文件已打开!\n");
	}
	char arr[1024] = "wenjancaozuo";
	
	fwrite(arr, 1, strlen(arr), fp);
	printf("%s\n", arr);
	fclose(fp);

	system("pause");
}

掌握以上操作就基本完成文件操作的内容。上面是数据块的读写函数。

附加

1、字符读写

先介绍两个句柄。

  1. stdin(键盘输入)

  2. stdout (标准输出)

fgetc(文件指针)  输入

fputc(字符常量 ,文件指针) 输出

//C语言
void main() {
	FILE* fp;
	fp = fopen("./test.txt","w");
	if (fp==NULL) {
		printf("文件不存在,打开失败!\n");
	}
	else {
		printf("文件已打开!\n");
	}
	int c;
	while ((c=fgetc(stdin))!=EOF){
		fputc(c, stdout);
		fputc(c, fp);
	}


	fclose(fp);
	
	system("pause");
}

2、字符串读写

fgets( 字符数组 , 字符长度 , 文件指针 )  输入

fputs( 字符串 ,文件指针 )  输出

//C语言
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main() {
	FILE* fp;
	fp = fopen("./test.txt","w");
	if (fp==NULL) {
		printf("文件不存在,打开失败!\n");
	}
	else {
		printf("文件已打开!\n");
	}

	char buf[1024] = "0";
	while (fgets(buf,sizeof(buf),stdin)!=NULL) {
		fputs(buf, stdout);
		fputs(buf, fp);
	}

	fclose(fp);
	
	system("pause");
}

文件的运用

文件到这里就学习完了。所以就要动手实践。现在将前面的动态内存通讯录进阶为文件通讯录。

//C语言
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define peoplemax 1000
//实现一个通讯录;
//通讯录可以用来存储1000个人的信息,每个人的信息包括:
//姓名、性别、年龄、电话、住址
//
//提供方法:
//1.	添加联系人信息
//2.	删除指定联系人信息
//3.	查找指定联系人信息
//4.	修改指定联系人信息
//5.	显示所有联系人信息
//6.	清空所有联系人
//7.	以名字排序所有联系人
//8.  保存联系人到文件
//9.  加载联系人

//先创建一个结构体数组。结构体里面包含个人信息。再加上一个人数

typedef struct FUNCTION {//定义1000长度的结构体数组
	char name[20];
	char sex[2];
	int age;
	char telnumber[11];
	char adress[20];
}ADbook;
struct BOOK {
	ADbook* address_book;
	int size;
	int personcount;
}as_book;

void Check_malloc() {
	if (as_book.size < as_book.personcount) {
		return;
	}
	as_book.personcount *= 2;
	ADbook* temp = (ADbook*)malloc
	(sizeof(ADbook)*as_book.personcount);
	for (int i = 0; i < as_book.size; i++) {
		temp[i] = as_book.address_book[i];
	}
	free(as_book.address_book);
	as_book.address_book = temp;
	printf("通讯录已经扩容!\n");
}
int book_menu() {
	int choice = 0;
	printf("=========<简易通讯录>=========\n");
	printf("=========<1、添加联系人>=========\n");
	printf("=========<2、删除联系人>=========\n");
	printf("=========<3、查找联系人>=========\n");
	printf("=========<4、修改联系人>=========\n");
	printf("=========<5、显示全部>==========\n");
	printf("=========<6、清空联系人>=========\n");
	printf("=========<7、排序联系人>=========\n");
	printf("=========<8、退出通讯录>=========\n");
	printf("请输入您的选择:");
	scanf("%d", &choice);
	return choice;
}
void empty_person() {//清空和初始化的相同作用。所以这里可以写成初始化
	as_book.size = 0;
	
	as_book.personcount = 5;
	as_book.address_book = (ADbook*)malloc
	(sizeof(ADbook)*as_book.personcount);
	//printf("通讯录已经初始化!\n");
}
void add_person() {
	Check_malloc();
	printf("请输入姓名:");
	scanf("%s", as_book.address_book[as_book.size].name);
	printf("请输入性别:");
	scanf("%s", as_book.address_book[as_book.size].sex);
	printf("请输入年龄:");
	scanf("%d", &as_book.address_book[as_book.size].age);
	printf("请输入电话:");
	scanf("%s", as_book.address_book[as_book.size].telnumber);
	printf("请输入地址:");
	scanf("%s", as_book.address_book[as_book.size].adress);

	printf("成功增加!\n");
	++as_book.size;
	printf("目前%d位联系人!\n", as_book.size);
}
int find_person() {
	char name[1024] = "0";
	printf("请输入查找人的姓名:");
	scanf("%s", name);
	int temp = 0;
	while (temp < as_book.size) {
		if (temp == 0) {
			printf("编号\t姓名\t性别\t年龄\t电话\t住址\n");
			printf("=================================================\n");
		}
		if (strcmp(name, as_book.address_book[temp].name) == 0) {
			printf("%d\t%s\t%s\t%d\t%s\t%s\t", as_book.size, as_book.address_book[temp].name, as_book.address_book[temp].sex
				, as_book.address_book[temp].age, as_book.address_book[temp].telnumber, as_book.address_book[temp].adress);
			printf("\n");
			return temp;
		}
		++temp;
	}

	printf("通讯录里没有该联系人!\n");
	return -1;
}
void del_person() {
	int temp = 0;
	temp = find_person();
	if (temp == 0) {
		;
	}
	else {
		while (temp < as_book.personcount) {
			as_book.address_book[temp] = as_book.address_book[temp + 1];
			++temp;
		}
		--as_book.personcount;
		printf("成功删除该联系人!\n");

	}
}
void alt_person() {
	int temp = 0;
	temp = find_person();
	if (temp == -1) {
		;
	}
	else {
		int choice = 0;
		int max = 5;
		while (max--) {//有五次修改机会,没选择一次就会减少一次。
			printf(" ======1、姓名 === 2、性别=======\n");
			printf(" ======3、年龄 === 4、电话=======\n");
			printf(" ======5、地址 === 6、跳过=======\n");
			printf("请选择要修改的项:");
			scanf("%d", &choice);
			switch (choice)
			{
			case 1:
				printf("姓名修改为:");
				scanf("%s", as_book.address_book[temp].name);
				break;
			case 2:
				printf("性别修改为:");
				scanf("%s", as_book.address_book[temp].sex);
				break;
			case 3:
				printf("年龄修改为:");
				scanf("%d", &as_book.address_book[temp].age);
				break;
			case 4:
				printf("电话修改为:");
				scanf("%s", as_book.address_book[temp].telnumber);
				break;
			case 5:
				printf("地址修改为:");
				scanf("%s", as_book.address_book[temp].adress);
				break;
			case 6:
				printf("请继续选择。\n");
				break;
			default:
				++max;//输入错误,加一次修改机会。
				break;
			}
		}
	}
}
void print_person() {
	if (as_book.size == 0) {
		printf("通讯录为空,请先添加联系人!\n");
	}
	else {
		int temp = 0;
		printf("编号\t姓名\t性别\t年龄\t电话\t住址\n");
		printf("=================================================\n");
		while (temp < as_book.size)
		{
			printf("%d\t%s\t%s\t%d\t%s\t%s\t", as_book.size, as_book.address_book[temp].name, as_book.address_book[temp].sex
				, as_book.address_book[temp].age, as_book.address_book[temp].telnumber, as_book.address_book[temp].adress);
			printf("\n");
			++temp;
		}
	}
}
//保存联系人
void save() {
	printf("正在保存……\n");
	FILE* fp = fopen("../ test.txt","w");
	if (fp==NULL) {
		printf("文件不存在,打开失败!\n");
		return;//结束程序
	}
	for (int temp = 0; temp < as_book.size; ++temp) {
		fwrite(&as_book.address_book[temp],sizeof(ADbook), 1 ,fp);
	}
	fclose(fp);
	printf("保存成功!\n");
	printf("已经保存 %d 条数据\n",as_book.size);
}
//加载联系人
void load() {
	printf("LOADING……\n");
	FILE* fp = fopen("../ test.txt", "r");
	if (fp == NULL) {
		printf("文件打开失败,加载失败\n");
		return;//结束程序
	}
	ADbook temp = { 0 };
	while (fread(&temp,sizeof(temp),1,fp)){
		Check_malloc();
		as_book.address_book[as_book.size] = temp;
		++as_book.size;

	}
	fclose(fp);
	printf("加载成功\n");
	printf("加载 %d 条联系人!\n",as_book.size);
}
void sort_person() {
	if (as_book.size == 0)
	{
		printf("通讯录为空,不需要排序!\n");
	}
	else
	{
		int row = 0;
		while (row < as_book.size - 1)
		{
			int col = 0;
			while (col < as_book.size - 1 - row)
			{
				if (strcmp(as_book.address_book[col].name, as_book.address_book[col + 1].name) > 0)
				{
					char temp[1024];
					strcpy(temp, as_book.address_book[col].name);
					strcpy(as_book.address_book[col].name, as_book.address_book[col + 1].name);
					strcpy(as_book.address_book[col + 1].name, temp);
				}
				++col;
			}
			++row;
		}
	}
}
int main() {
	int choice = 0;
	empty_person();
	load();
	//以循环打印菜单提示用户输入选择
	while (1) {
		//开关语句卡是实现函数,增删查改,排序,清空。
		choice = book_menu();
		switch (choice) {
		case 1://添加联系人
			add_person();
			save();
			break;
		case 2://删除联系人
			del_person();
			save();
			break;
		case 3://查找联系人
			find_person();
			break;
		case 4://修改联系人
			alt_person();
			save();
			break;
		case 5://显示所有联系人
			print_person();
			break;
		case 6://清空联系人
			empty_person();
			save();
			break;
		case 7://排序联系人
			sort_person();
			save();
			break;
		case 8:
			save();
			printf("欢迎下次使用!\n");
			system("pause");
			return 0;
			break;
		default:
			break;
		}
	}
	return 0;
	system("pause");
}

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值