本文介绍了c语言的文件操作,重点阐释了各个文件操作函数的作用,总结了日常使用文件操作的方法,加深对文件操作的理解。
一、文件
1.文件分类
文件可以分为为文本文件或者二进制文件。数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
2.文件缓冲区
ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓 冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定。
简单说,就是把要处理的都赞到一起,等攒够了在送给系统统一处理。(有点像垃圾桶,等垃圾桶装满了在去倒)。
与缓存的区别
于此对应的还有一个缓存,这两个是不同的概念,缓存是经常使用的数据开辟一块空间存进去,而这块空间就是缓存。虽然两个都是为提升程序的运行效率,但是还是有本质的区别的。
二、文件操作函数介绍
1.打开关闭文件函数
FILE * fopen ( const char * filename, const char * mode );
int fclose ( FILE * stream );
打开方式如下(网上找的比较全的图,t可以省略)
简单打开文件的例子:
#include<stdio.h>
int main ()
{
FILE * pFile;
pFile = fopen ("test.txt","w"); //写方式打开
if (pFile!=NULL)
{
fputs ("fopen example",pFile);
fclose (pFile);
}
return 0;
}
2.读写操作
全部读写函数如下:
着重介绍以下四个常用的读写操作:
2.1 fread()
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
#include<stdio.h>
int main()
{
FILE *pFile;
char buff[1024] = "hello";
pFile = fopen("test.txt", "w+");
fwrite(buff, 1,11,pFile);
fclose(pFile);
return 0;
}
#include<stdio.h>
int main()
{
FILE *pFile;
char buff[1024] = " ";
pFile = fopen("test.txt", "w+");
fread(buff, 1,11,pFile);
fclose(pFile);
return 0;
}
2.2 fwrite()
size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
#include<stdio.h>
int main()
{
FILE *pFile;
char buff[1024] = "hello";
pFile = fopen("test.txt", "w+");
fwrite(buff, 1,11,pFile);
fclose(pFile);
return 0;
}
2.3 fprintf()
int fprintf( FILE *stream, const char *format [, argument ]...);
#include<stdio.h>
int main()
{
FILE *pFile;
pFile = fopen("test.txt", "w+");
fprintf(pFile, "hello world");
fclose(pFile);
return 0;
}
2.4 fscanf()
int fscanf( FILE *stream, const char *format [, argument ]... );
格式化读入,文件格式如图:
#include<stdio.h>
int main()
{
FILE *pFile;
char buff[1024] = "";
int num = 5;
char str = "";
pFile = fopen("test.txt", "r+");
fscanf(pFile, "%s %d %s", buff, &num, &str);
fclose(pFile);
return 0;
}
三、通讯录最终文件版
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef void(*Func)();
typedef struct PersonInfo
{
char name[1024];
char sex[1024];
char age[1024];
char phone[1024];
char adress[1024];
} PersonInfo;
typedef struct AdressBook
{
PersonInfo *persons;
int capacity;
int size;
} AdressBook;
AdressBook g_address_book;
void Init()
{
g_address_book.size = 0;
g_address_book.capacity = 100;
g_address_book.persons = (PersonInfo *)malloc(g_address_book.capacity * sizeof(PersonInfo));
for (int i = 0; i < g_address_book.capacity; i++)
{
g_address_book.persons[i].name[0] = '\0';
g_address_book.persons[i].phone[0] = '\0';
g_address_book.persons[i].adress[0] = '\0';
g_address_book.persons[i].sex[0] = '\0';
g_address_book.persons[i].age[0] = '\0';
}
}
int Menu()
{
int i = -1;
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(" 9. 加载联系人\n");
printf(" 0. 退出\n");
printf("========================\n");
printf("请输入要选择操作的序号:");
fflush(stdin);
scanf("%d", &i);
return i;
}
int Judge_Input_Legal(int choice)
{
if (choice < 0 || choice > 9)
{
printf("输入有误请重新输入!\n");
return -1;
}
if (choice == 0)
{
printf("Goodbye\n");
return 0;
}
return choice;
}
void Empty()
{
//TMOD
}
void Add_Contact()
{
PersonInfo *person_info = &g_address_book.persons[g_address_book.size];
if (g_address_book.size >= g_address_book.capacity)
{
printf("内存已满进行扩容");
g_address_book.capacity = 2 * g_address_book.capacity;
//g_address_book.persons = (PersonInfo *)realloc(g_address_book.persons, g_address_book.capacity * sizeof(PersonInfo));
PersonInfo *p = (PersonInfo *)malloc(g_address_book.capacity * sizeof(PersonInfo));
for (int i = 0; i < g_address_book.size; i++)
{
p[i] = person_info[i];
}
free(g_address_book.persons);
g_address_book.persons = p;
}
printf("请输入要添加联系人的信息:\n");
printf("输入姓名:");
scanf("%s", person_info->name);
printf("输入性别:");
scanf("%s", person_info->sex);
printf("输入年龄:");
scanf("%s", person_info->age);
printf("输入电话:");
scanf("%s", person_info->phone);
printf("输入地址:");
scanf("%s", person_info->adress);
g_address_book.size++;
printf("添加联系人成功\n");
}
void Delet_Contact()
{
PersonInfo *person_info = &g_address_book.persons;
int num = 0;
printf("请输入要删除联系人的序号:");
scanf("%d", &num);
if (num < 0 || num >=g_address_book.size)
{
printf("输入有误");
return;
}
*(person_info + num) = *(person_info + g_address_book.size - 1);
g_address_book.size--;
printf("删除联系人成功\n");
}
void Search_Contact()
{
char search_name[1024] = " ";
PersonInfo *person_info = &g_address_book.persons;
printf("请输入要查找的姓名:");
scanf("%s", search_name);
for (int i = 0; i < g_address_book.size; i++)
{
if (0 == strcmp((g_address_book.persons + i)->name, search_name))
{
printf("[%d]\t%s\t%s\t%s\t%s\t%s\n",
i,
(person_info + i)->name,
(person_info + i)->sex,
(person_info + i)->age,
(person_info + i)->phone,
(person_info + i)->adress
);
}
}
}
void Update_Contact()
{
int num = 0;
PersonInfo *person_info = &g_address_book.persons;
printf("请输入要修改的序号:");
scanf("%d", &num);
printf("请输入新的姓名:");
scanf("%s", (person_info + num)->name);
printf("请输入新的性别:");
scanf("%s", (person_info + num)->sex);
printf("请输入新的年龄:");
scanf("%s", (person_info + num)->age);
printf("请输入新的电话:");
scanf("%s", (person_info + num)->phone);
printf("请输入新的住址:");
scanf("%s", (person_info + num)->adress);
printf("联系人信息修改成功\n");
}
void Print_Contact()
{
PersonInfo *person_info = &g_address_book.persons;
printf("打印共%d条联系人信息如下:\n", g_address_book.size);
printf("序号\t姓名\t性别\t年龄\t电话\t住址\n");
for (int i = 0; i < g_address_book.size; i++)
{
printf("[%d]\t%s\t%s\t%s\t%s\t%s\n",
i,
(g_address_book.persons + i)->name,
(g_address_book.persons+ i)->sex,
(g_address_book.persons+ i)->age,
(g_address_book.persons+ i)->phone,
(g_address_book.persons+ i)->adress
);
}
printf("打印全部信息成功\n");
}
void Clear_Contact()
{
g_address_book.size = 0;
printf("全部清空成功");
}
void Sort_Contact()
{
PersonInfo *person_info = &g_address_book.persons;
//PersonInfo *PersonInfo_tmp = &g_address_book.persons[g_address_book.size+1];
char PersonInfo_tmp[1024] = " ";
for (int i = 0; i < g_address_book.size; i++)
{
for (int j = 0; j < g_address_book.size - i-1; j++)
{
if (strcmp((person_info + j)->name, (person_info + j + 1)->name) > 0)
{
//*PersonInfo_tmp = *(person_info + j);
//*(person_info + j) = *(person_info + j + 1);
//*(person_info + j + 1) = *PersonInfo_tmp;
strcpy(PersonInfo_tmp, person_info + j);
strcpy(person_info + j, person_info + j + 1);
strcpy(person_info + j + 1, PersonInfo_tmp);
}
}
}
printf("排序成功\n");
}
void Save_Contact_file()
{
PersonInfo *person_info = &g_address_book.persons;
FILE *pFile;
pFile = fopen("Contacts.txt", "w");
fprintf(pFile, "%d\n",g_address_book.size);
fprintf(pFile, "序号\t姓名\t性别\t年龄\t电话\t住址\n");
for (int i = 0; i < g_address_book.size; i++)
{
fprintf(pFile,"[%d]\t%s\t%s\t%s\t%s\t%s\n",
i,
(g_address_book.persons + i)->name,
(g_address_book.persons+ i)->sex,
(g_address_book.persons+ i)->age,
(g_address_book.persons+ i)->phone,
(g_address_book.persons+ i)->adress
);
}
fclose(pFile);
printf("保存信息成功!\n");
}
void Load_Contact()
{
int num = 0;
PersonInfo *person_info = &g_address_book.persons;
FILE *pFile;
pFile = fopen("Contacts.txt", "r");
fscanf(pFile, "%d\n",&g_address_book.size);
fscanf(pFile, "%[^\n]%*c\n");
for (int i = 0; i < g_address_book.size; i++)
{
fscanf(pFile, "[%d]\t%s\t%s\t%s\t%s\t%s\n",
&num,
(g_address_book.persons + i)->name,
(g_address_book.persons+ i)->sex,
(g_address_book.persons+ i)->age,
(g_address_book.persons+ i)->phone,
(g_address_book.persons+ i)->adress
);
}
fclose(pFile);
printf("信息读取成功!\n");
}
int main()
{
Func arr[] =
{
Empty,//无作用,只为把数组0号元素占用,使序号与数组下标对应
Add_Contact,
Delet_Contact,
Search_Contact,
Update_Contact,
Print_Contact,
Clear_Contact,
Sort_Contact,
Save_Contact_file,
Load_Contact
};
Init();
while (1)
{
int choice = Menu(); //打印菜单并读取用户输入
choice = Judge_Input_Legal(choice);
if(choice == 0) break; //判断用户输入是否合法
if(choice < 0) continue;
arr[choice]();//转移表调用函数
}
return 0;
}