文件是计算机存储设备中用于存储数据的容器。
为什么需要文件?
- 当程序终止时,所有数据都会丢失。即使程序终止,存储在文件中也会保留您的数据。
- 如果必须输入大量数据,则将花费大量时间来全部输入。
但是,如果您有一个包含所有数据的文件,则可以使用C中的一些命令轻松地访问文件的内容。
- 您可以轻松地将数据从一台计算机移动到另一台计算机,而无需进行任何更改。
文件类型
但是,如果您有一个包含所有数据的文件,则可以使用C中的一些命令轻松地访问文件的内容。
处理文件时,应了解两种类型的文件:
- 文字档
- 二进制文件
1.文本文件
文本文件是普通的.txt文件。您可以使用任何简单的文本编辑器(例如记事本)轻松创建文本文件。
打开这些文件时,您将以纯文本形式看到文件中的所有内容。您可以轻松地编辑或删除内容。
它们以最少的维护工作,易于阅读,提供最少的安全性并占用更大的存储空间。
2.二进制文件
二进制文件主要是计算机中的.bin文件。
它们不是以纯文本格式存储数据,而是以二进制格式(0和1)存储数据。
与文本文件相比,它们可以容纳更多数据,不易读取,并提供更好的安全性。
文件操作
在C中,您可以对文件执行四个主要操作,即文本或二进制:
- 创建一个新文件
- 打开现有文件
- 关闭档案
- 读取信息并将信息写入文件
处理文件
处理文件时,需要声明文件类型的指针。文件和程序之间的通信需要此声明。
FILE *fptr;
打开文件-用于创建和编辑
使用stdio.h
头文件中定义的fopen()
函数执行fopen()
文件。
在标准I / O中打开文件的语法为:
ptr = fopen("fileopen","mode");
例如,
fopen("E:\\cprogram\\newprogram.txt","w");
fopen("E:\\cprogram\\oldprogram.bin","rb");
- 假设文件
newprogram.txt
在E:\cprogram
位置不存在。第一个函数创建一个名为newprogram.txt
的新文件,并按照‘w’模式打开该文件进行写入。
写入模式允许您创建和编辑(覆盖)文件的内容。 - 现在,我们假设第二个二进制文件
oldprogram.bin
位于E:\cprogram
位置。第二个函数打开现有文件,以二进制模式‘rb’读取。
读取模式仅允许您读取文件,而不能写入文件。
Mode | Meaning of Mode | During Inexistence of file |
---|---|---|
r |
Open for reading. | If the file does not exist, fopen() returns NULL. |
rb |
Open for reading in binary mode. | If the file does not exist, fopen() returns NULL. |
w |
Open for writing. | If the file exists, its contents are overwritten. If the file does not exist, it will be created. |
wb |
Open for writing in binary mode. | If the file exists, its contents are overwritten. If the file does not exist, it will be created. |
a |
Open for append. Data is added to the end of the file. |
If the file does not exist, it will be created. |
ab |
Open for append in binary mode. Data is added to the end of the file. |
If the file does not exist, it will be created. |
r+ |
Open for both reading and writing. | If the file does not exist, fopen() returns NULL. |
rb+ |
Open for both reading and writing in binary mode. | If the file does not exist, fopen() returns NULL. |
w+ |
Open for both reading and writing. | If the file exists, its contents are overwritten. If the file does not exist, it will be created. |
wb+ |
Open for both reading and writing in binary mode. | If the file exists, its contents are overwritten. If the file does not exist, it will be created. |
a+ |
Open for both reading and appending. | If the file does not exist, it will be created. |
ab+ |
Open for both reading and appending in binary mode. | If the file does not exist, it will be created. |
关闭档案
读取/写入后,应关闭文件(文本文件和二进制文件)。
使用fclose()
函数执行关闭文件。
fclose(fptr);
在这里, fptr
是与要关闭的文件关联的文件指针。
读取和写入文本文件
为了读取和写入文本文件,我们使用函数fprintf()
和fscanf().
它们只是printf()
和scanf()
的文件版本。唯一的区别是fprint()
和fscanf()
需要指向结构FILE的指针。
示例1:写入文本文件
#include
#include
int main()
{
int num;
FILE *fptr;
// use appropriate location if you are using MacOS or Linux
fptr = fopen("C:\\program.txt","w");
if(fptr == NULL)
{
printf("Error!");
exit(1);
}
printf("Enter num: ");
scanf("%d",&num);
fprintf(fptr,"%d",num);
fclose(fptr);
return 0;
}
该程序从用户那里获取一个号码,并将其存储在文件program.txt
。
编译并运行该程序后,您会看到在计算机的C驱动器中创建的文本文件program.txt
。打开文件时,您可以看到输入的整数。
示例2:从文本文件读取
#include
#include
int main()
{
int num;
FILE *fptr;
if ((fptr = fopen("C:\\program.txt","r")) == NULL){
printf("Error! opening file");
// Program exits if the file pointer returns NULL.
exit(1);
}
fscanf(fptr,"%d", &num);
printf("Value of n=%d", num);
fclose(fptr);
return 0;
}
该程序读取program.txt
文件中存在的整数并将其打印到屏幕上。
如果您从示例1成功创建了文件,运行此程序将为您提供输入的整数。
其他功能,如fgetchar()
, fputc()
等,也可以类似的方式使用。
读写二进制文件
在二进制文件的情况下,函数fread()
和fwrite()
分别用于读取和写入磁盘上的文件。
写入二进制文件
要写入二进制文件,需要使用fwrite()
函数。这些函数采用四个参数:
- 要写入磁盘的数据地址
- 要写入磁盘的数据大小
- 此类数据的数量
- 指向要写入的文件的指针。
fwrite(addressData, sizeData, numbersData, pointerToFile);
示例3:使用fwrite()写入二进制文件
#include
#include
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen("C:\\program.bin","wb")) == NULL){
printf("Error! opening file");
// Program exits if the file pointer returns NULL.
exit(1);
}
for(n = 1; n < 5; ++n)
{
num.n1 = n;
num.n2 = 5*n;
num.n3 = 5*n + 1;
fwrite(&num, sizeof(struct threeNum), 1, fptr);
}
fclose(fptr);
return 0;
}
在此程序中,我们在C驱动器中创建一个新文件program.bin
。
我们声明一个具有三个数字n1,n2和n3的结构threeNum
,并在主函数中将其定义为num。
现在,在for循环内,我们使用fwrite()
将值存储到文件中。
第一个参数使用num的地址,第二个参数使用结构threeNum
的大小。
由于我们仅插入num的一个实例,因此第三个参数是1
。并且,最后一个参数*fptr
指向我们正在存储数据的文件。
最后,我们关闭文件。
从二进制文件读取
函数fread()
也采用4个参数,类似于上面的fwrite()
函数 。
fread(addressData, sizeData, numbersData, pointerToFile);
示例4:使用fread()从二进制文件读取
#include
#include
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen("C:\\program.bin","rb")) == NULL){
printf("Error! opening file");
// Program exits if the file pointer returns NULL.
exit(1);
}
for(n = 1; n < 5; ++n)
{
fread(&num, sizeof(struct threeNum), 1, fptr);
printf("n1: %d\tn2: %d\tn3: %d", num.n1, num.n2, num.n3);
}
fclose(fptr);
return 0;
}
在此程序中,您读取相同的文件program.bin
并逐个循环浏览记录。
简单来说,你读一个threeNum
的记录threeNum
大小从文件中指出由* FPTR到结构NUM。
您将获得与示例3中插入的记录相同的记录。
使用fseek()获取数据
如果文件中有许多记录,并且需要访问特定位置的记录,则需要遍历所有记录才能获取该记录。
这将浪费大量的内存和操作时间。使用fseek()
可以更轻松地获取所需数据。
顾名思义, fseek()
光标搜索到文件中的给定记录。
fseek()的语法
fseek(FILE * stream, long int offset, int whence);
第一个参数流是指向文件的指针。第二个参数是要查找的记录的位置,第三个参数指定偏移量开始的位置。
Whence | Meaning |
---|---|
SEEK_SET |
Starts the offset from the beginning of the file. |
SEEK_END |
Starts the offset from the end of the file. |
SEEK_CUR |
Starts the offset from the current location of the cursor in the file. |
示例5:fseek()
#include
#include
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen("C:\\program.bin","rb")) == NULL){
printf("Error! opening file");
// Program exits if the file pointer returns NULL.
exit(1);
}
// Moves the cursor to the end of the file
fseek(fptr, -sizeof(struct threeNum), SEEK_END);
for(n = 1; n < 5; ++n)
{
fread(&num, sizeof(struct threeNum), 1, fptr);
printf("n1: %d\tn2: %d\tn3: %d\n", num.n1, num.n2, num.n3);
fseek(fptr, -2*sizeof(struct threeNum), SEEK_CUR);
}
fclose(fptr);
return 0;
}
该程序将以相反的顺序(从最后到第一)开始从文件program.bin
中读取记录并进行打印。