C语言文件操作
操作 | 例 |
---|---|
定义文件指针 | FILE *fp; |
打开文件 | fp = fopen(“1.txt”,“w”); |
文件的打开方式 | w表示写文本文件,r表示读文本文件,wb表示写文件中文件,rb表示读文件文件,a表示向文件末尾追加数据 |
关闭文件 | fclose(fp); |
从文件中读字符 | fgetc(fp); |
向文件中写字符 | fputc(ch,fp); |
从文件中读字符串 | fgets(str,N,fp); |
向文件中写字符串 | fgets(str,fp); |
按格式读文件 | fscanf(fp,"%c",&ch[i]); |
按格式写文件 | fprintf(fp,"%d",number); |
按数据块读文件 | fread(&stu[i],sizeof(STUDENT),1,fp); |
按数据块写文件 | fwrite(stu,sizeof(STUDENT),n,fp); |
一、文本文件(ASCII码文件)和二进制文件
C语言文件有两种类型,它们的差别在于储存数值型数据的方式不同。二进制文件中,数值型数据都是以二进制形式存储的;而在文本文件中,则是将数值型数据的每一位数字作为一个字符以其ASCII码的形式存储的。
文本文件中每一个数字都单独占用一个字节的存储空间。
二进制文件则是把整个数字作为一个二进制数来存储的,并非数值的每一位数都占用单
独的存储空间。
C语言文件一律把数据看成是由字节构成的序列,即字节流。对文件的存取也是以字节为单位的,输入/输出的数据流仅受程序控制而不受物理符号(如回车换行)的控制。故C语言文件又称流式文件。
C语言有缓存型和非缓冲型两种文件系统
缓存型文件系统是指系统自动存在内存中为每一个正在使用的文件开辟一个缓冲区,作为程序与文件之间数据交换的中间媒介。缓存文件利用文件指针标识文件。
非缓冲文件系统不会自动设置文件缓冲区,需由程序员自己设定。非缓冲文件系统没有文件指针,它使用称为文件号的整数来标识文件。缓冲型文件系统中的文件操作,也称为高级文件操作。
二、文件的打开和关闭
1、打开文件(fopen()函数用来打开文件)
函数原型:FILE *fopen(const char *filename,const char *mode);
FILE是在stdio.h中定义的结构体类型,封装与文件信息有关的信息,如文件句柄、位置指针及缓冲区等。缓冲文件系统为每个被使用的文件在内存中开辟一个缓冲区,用来存放文件的有关信息,这些信息被保存在一个FILE的结构类型的变量中。
fopen()的返回值是一个文件指针,fopen()有两个形参,第一个形参filename表示文件名,可包含路径和文件名,第二个形参mode表示文件的打开方式。
例: fopen("1.txt", "r");
文件的打开方式
字符 | 含义 |
---|---|
“r” | 以只读的方式,打开文本文件。该文件必须是已经存在的,若文件不存在,则会出错 |
“w” | 以只写的方式,创建并打开文本文件,已存在的文件将被覆盖 |
“a” | 以只写的方式,打开文本文件,位置指针移动到文件末尾,向文件末尾添加数据,原文件数据保留。若文件不存在,则会出错 |
“+” | 与上面的字符串组合,表示以读写的方式打开文本文件 |
“b” | 打开二进制文件 |
2、关闭文件(fclose()函数用来关闭文件)
函数原型:int fclose(FILE *fp)
当文件关闭成功时,返回0值
当文件关闭不成功时,返回一个非0值
由于操作系统对于同时打开的文件数目有限制,所以在文件使用后必须关闭文件。
3、例:打开文件并进行判断和关闭文件
当文件不存在或已经损坏时,文件打开会失败。所以每次打开文件都需要判断是否打开成功。若打开失败,则函数fopen()返回空指针NULL。因此可以检查fopen()返回值是否为NULL来判断文件打开是否成功。
#include<stdio.h>
int main(){
FILE *fp;
fp = fopen("1.txt", "r");
if(fp){
printf("Success!\n");
fclose(fp);
}
else
printf("Fail!\n");
}
三、按字符读写文件
1、读写文件中的字符
(1)函数fgetc()用于读打开文件的字符
函数原型:int fgetc(FILE *fp);
fp是由函数fopen()返回的文件指针,该函数的功能从fp所指的文件中读取一个字符,并将指针指向下一个字符。若读取成功,则返回该字符。若读到文件末尾,则返回EOF
(EOF为一个常量,在stdio.h中定义为-1)。
例:
FILE *fp;
char ch;
ch = fgetc(fp);
fclose(fp);
(2)函数fputc()用于将一个字符写到一个文件上
函数原型:int fputc(int c,FILE *fp);
c是要输出的字符。该函数功能是将字符c写入到文件指针fp所指的文件中。若写入错误,返回NULL,否则返回字符c。
例:
FILE *fp;
char ch;
ch = getchar();
fputc(ch,fp);
fclose(fp);
2、读写文件中的字符串
(1)函数fgets()从文件读取字符串
函数原型:char *fgets(char *s,int n,FILE *fp);
改函数从fp所指的文件中读取字符串并在字符串末尾加’\0’,然后存入s,最多n-1个字符。当读到回车换行符、达到文件末尾、或读满n-1个字符时,函数返回字符串的首地址,即指针s的值;读取失败时返回NULL(空指针)。出错和达到文件末尾时都返回NULL。
例:
char str[80];
FILE *fp;
fgets(s,80,fp);
puts(str);
fclose(fp);
(2)函数fputs()将字符串写入文件中
函数原型:int fputs(const char *s,FILE *fp);
若写入错误,返回EOF,否则返回一个非负数。
例:
char str[80];
FILE *fp;
gets(str);
fputs(str,fp);
fclose(fp);
四、按格式读写文件
1、函数fprintf()按指定格式将数据写入文件中
函数原型:int fprintf(FILE *fp,const char *format,…);
fp为文件指针,format为格式控制参数,第3个参数为输出参数列表(后两个参数和返回值和函数printf()相同)
例:
fprintf(fp,"%d",number);
2、函数fscanf()按指定格式从文件中读文件数据
函数原型:int fscanf(FILE *fp,const char *format,…);
fp为文件指针,format为格式控制参数,第3个参数为地址参数列表(后两个参数和返回值和函数scanf()相同)
例:
fscanf(fp,"%c",&ch[i]);
五、按数据块读写文件
fread()和fwrite()用于一次读取一组数据。
#include <stdio.h>
#include <stdlib.h>
#define N 80
typedef struct student{
char studentName[10];
char studentID[10];
}STUDENT;
int main(){
STUDENT stu[N];
FILE *fp;
1、函数fwrite()按数据块将数据写入文件中
函数原型:unsigned int fwrite(const void *buffer,unsigned int size,unsigned int count,FILE *fp);
fwrite()的功能是将buffer指向的内存中的数据块写入fp所指的文件。函数返回的是实际写入的数据块个数。
buffer是待输出数据块的起始地址。
size是每个数据块的大小(待输出的每个数据块的字节数)。
count是最多允许写入的数据块个数。
//按数据块写入内容
if((fp = fopen("1.txt","w")) == NULL){
printf("Open fail!\n");
exit(0);
}
int i,n;
printf("The number of students:");
scanf("%d",&n);
for(i = 0;i < n;i++){
printf("Enter student message(name,ID):");
scanf("%s %s",stu[i].studentName,stu[i].studentID);
}
fwrite(stu,sizeof(STUDENT),n,fp);
fclose(fp);
2、函数fread()按数据块从文件中读文件数据
函数原型:unsigned int fread(void *buffer,unsigned int size,unsigned int count,FILE *fp);
fread()的功能是从fp所指的文件中读取数据块并储存到buffer所指的内存中。函数返回的是实际写入的数据块个数。
buffer是待读入数据块的起始地址。
size是每个数据块的大小(待读入的每个数据块的字节数)。
count是最多允许读取的数据块个数。
//按数据块读取内容
if((fp = fopen("1.txt","r")) == NULL){
printf("Open fail!\n");
exit(0);
}
for(i = 0; !feof(fp);i++){
fread(&stu[i],sizeof(STUDENT),1,fp);
printf("%s ",stu[i].studentName);
printf("%s ",stu[i].studentID);
}
fclose(fp);
return 0;
}
六、检查文件
1、函数ferror()用来检测是否出现文件错误
如果出现错误,函数返回一个非0值,否则返回0值。
例:
if(ferror(fp))
printf("Error on file!\n");
2、函数feof()检查是否达到文件末尾
函数原型:int feof(FILE *fp);
当前文件位置指针指向文件结束符时,返回0值,否则返回非0值。
函数feof()总是在读完文件所有内容后再执行一次读文件操作(将文件结束符读走,但不显示)才能返回真值(非0值)。
例:
while(!feof(fp)){
.......
}