C语言文件操作详解
1.文件指针
在C语言中,定义一个文件指针的方法为:FILE *文件指针名;FILE 为大写,它实际是系统定义的一个结构体,里面包含有文件名、文件大小、路径、状态等信息。然后我们就可以通过指针名去访问文件的信息,实现对文件的操作。
2.文件的使用方式
r : 只读权限,该文件必须存在
w : 只写权限,若文件不存在,就创建一个文件,若存在,就清空文件然后再写内容。
rb+ : 读写权限打开一个二进制文件
rt+ : 读写打开一个文本文件,允许读和写。
r+ : 可读可写权限打开文件
w+ : 可读可写权限打开文件
a : 以可附加的形式打开只写文件,若文件不存在,会创建这个文件,如存在,在文件的末尾追加内容,原先的文件保留。(EOF符保留)
a+ : 以可附加的形式打开可读写文件,若文件不存在,会创建这个文件,如存在,在文件的末尾追加内容,原先的文件保留。(EOF符保留)
awb : 只写打开或新建一个二进制文件;只允许写数据。
wb+ : 读写打开或建立一个二进制文件,允许读和写。
wt+ : 读写打开或着建立一个文本文件;允许读写。
at+ : 读写打开一个文本文件,允许读或在文本末追加数据。
ab+ : 读写打开一个二进制文件,允许读或在文件末追加数据。
文件使用方式由r,w,a,t,b,+六个字符拼成,各字符的含义是:
r(read): 读
w(write): 写
a(append): 追加
t(text): 文本文件,可省略不写
b(banary): 二进制文件
+: 读和写
3.文件的打开和关闭
文件的打开函数:fopen()
格式:文件指针名 = fopen(文件名,使用文件方式);
其中:
文件指针名必须是 FILE*类型的指针变量
文件名:被打开的文件名。若有文件就打开,若无则创建该文件
使用文件方式:文件操作的类型和要求
例子:
FILE *fp;
fp = fopen("text","w+");
文件的关闭函数:fclose()
格式: fclose(文件指针名);
一般fclose和fopen配对使用,若前面有fopen函数,在操作文件结束后就需要使用fclose函数来关闭这个文件,传入的参数为指向那个文件的FILE* 类型的指针变量。函数的返回值为0.如不为0说明有问题
4.文件的读和写
C语言中提供了四种文件的读和写方法,这些方法都需要包含头文件<stdio.h>:
①字符读写函数:fgetc()和fputc()
②字符串读写函数:fgets()和fputs()
③数据块读写函数:fread()和fwrite()
④格式化读写函数:fscanf()和fprintf()
定义一个指针变量FILE *fp;
一、字符读写函数:fgetc() 和 fputc()
1)fgetc():字符读函数
fget函数是从指定的文件中读取一个字符,格式为 字符变量 = fgetc(文件指针);
例如:char ch; ch = fgetc(fp);从fp指向的文件中读取一个字符,用ch来接收
说明:fgetc函数调用的文件,必须是可读的文件,而且在文件内部有一个指针,用fgetc函数后,该指针会自动往后移动一个字节,所有可以多次调用fgetc函数,读取多个字符。但是该指针和文件指针不是一个概念,该指针是文件内部的指针,指的是文件内部的内容,而文件指针指的是文件的位置、状态等信息。
2)fputc():字符写函数
fputc函数是将一个字符写到指定的文件中去。格式: fputc(字符量,文件指针);
例子: fputc(ch,fp);将ch代表的字符写到fp指向的文件中去。
说明: 被写入的文件,必须是可写、读写、追加方式打开的文件,每写入一个字符,文件内部指针就会向后移动一个字节,fputc有一个返回值,如写入成功则返回一个字符,否则返回一个EOF。
字符读写函数例子:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 40
int main(int argc ,char *argv[]){
FILE *inFile,*outFile;//定义一个读文件指针和一个写文件指针
char fname[SIZE]; //定义一个字符数组
char ch;//作为一个字符,接收fgetc获取的一个字符。
inFile = fopen(argv[1],"r"); //打开一个文件,该文件需要main函数接收一个文件名参数
if (inFile == NULL){
perror("inFile"); //如果文件打开错误,按照系统报错方式提示错误信息
exit(1); //退出程序
}
outFile = fopen("fileCopy","a+");//同上
if (inFile == NULL){
perror("outFile");
exit(2);
}
while((ch = fgetc(inFile)) !=EOF){ //如果fgetc函数返回的结果不是EOF结束标志,则说明读字符成功
fputc(ch,outFile); //将字符写入到要写入的文件中去。
}
fclose(inFile);
fclose(outFile);
return 0;
}
二、字符串读写函数fgets 和 fputs
1)fgets读字符串函数:是从一个指定的文件中读一个字符串到字符数组中,格式为:
fgets(字符数组名,n,文件名);n表示一个整数,表示从文件中读取不超过n-1个字符的字符串,在读入的末尾要加一个'\0'.如fgets(str,n,fp);表示从fp中读取n-1个字符串到str数组中。
说明:再读出n-1个字符前,如遇到换行符或EOF,则读结束,fgers函数的返回值为字符数组的首地址。
2)fputs写字符串函数:向指定的文件中写入一个字符串 ,格式为:fputs(字符串,文件指针); 其中字符串可以为字符常量,也可以是字符数组。文件指针指向的是文件
例如:fputs(buf,fp);将buf数组总的内存写到fp指向的文件中
字符串读写函数例子:
#include <stdio.h>
#include <string.h>
int main(void){
FILE *fp; //定义一个文件指针
char buf[BUFSIZ]; //字符数组 长度为BUFSIZ其值为1024
if((fgets(buf,BUFSIZ,stdin)) != NULL){ //以stdin的方式从键盘输入字符,读入到buf数组中,最大长度为BUFSIZ - 1
buf[BUFSIZ - 1] = '\0'; //将数组的最后一个内存设置为结束标志
fp = fopen("file.txt","w+");//以读写方式打开文件
fputs(buf,fp); //将buf数组的内容写入到fp指向的文件中
}
return 0;
}
三、数据块读写函数fread 和 fwrite
1)fread:读取一组数据,如一个数组元素,一个结构体变量的值等。格式:
fread(buffer,size,count,fp);
2)fwrite:写入一组数据,如上;格式:fwrite(buffer,size,count,fp);
其中:
buffer: 是一个指针,在fread函数中,表示存放读入数据的首地址,在fwrite函数中,表示存放要写的数据的首地址。
size:表示数据块的字节数
count:表示要读写的数据块块数
fp:表示指向文件的指针。
例子:
fwrite例子
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define nameLen 40
#define stuNum 3
int main(int argc,char *argv[]){
typedef struct{
char name[nameLen];
int age;
int stuNo;
}STUDENT;//定义一个STUDENT结构体
char name[stuNum][nameLen] = {
"pingping",
"cuicui",
"jingjing",
};//定义一个二维数组name,
STUDENT students[stuNum] = {0};
for(int i = 0 ; i < stuNum ; i++){
strncpy (students[i].name,name[i],nameLen - 1);//将name的值复制到students的name中,
students[i].age = 18+i;
students[i].stuNo = 110+i;
}
FILE *fp;
fp = fopen("studentList.txt","w+");//以可读写的方式打开文件studentList.txt
if(fp == NULL){
perror("fopen");
exit(1);
}
fwrite(students,sizeof(STUDENT),stuNum,fp);//将结构体的内容以结构体的大小,写到fp文件中,写入stuNum次
fclose(fp); //关闭文件
return 0;
}
fread函数例子(参照上面的fwrite)
fread(students,sizeof(STUDENT),stuNum,fp);//将文件中的内容以结构体的大小,读入到students数组中,读入stuNum次
for(int i = 0 ; i < stuNum; i++){ //for循环打印students读入的数据
printf("student's name is %s\n",students[i].name);
printf("student'age is %d\n",students[i].age);
printf("student'stuNo is %d\n",students[i].stuNo);
}
fclose(fp);
四、格式化读写函数fscanf 和 fprintf
这两个函数和scanf和printf的功能相似,都是格式化读写函数,区别在于这两个函数读写的对象不是键盘和显示器,而是磁盘上面的文件
格式:
fscanf(文件指针,格式化字符串,输入列表);
fprintf(文件指针,格式化字符串,输出列表);
如:
fscanf(fp,"%s",ch);
fprintf(fp,"%s",ch);
例子:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 40
int main(void){
//声明一个文件指针
FILE *fp;
char words[SIZE];
char outWords[SIZE];
fp = fopen("text","w+");
if(fp == NULL){ //判断fp为空
printf("file is not found\n");
}
puts("please input a str:");
puts("start:");
while (gets(words) != NULL && words[0] != '\0')
fprintf(fp,"%s",words);//以fp的内容以格式化符的形式写入到words中。
puts(words);//打印words数组
rewind(fp);//将fp重新指向文件的头位置
while( fscanf(fp,"%s",outWords)== 1){ //fscanf将fp中得内容以格式化%s的形式读入到outWords数组中,该函数返回值为1,表示成功,不为1,说明有错误
puts(outWords);//打印outWords数组的内存
}
}
5.文件随机读写函数
移动文件内部指针位置的函数有两个:rewind 和 fseek
rewind(文件指针):将文件指针移动到文件头
fseek(文件指针,位移量,起始点)
文件指针:指向被移动的文件
位移量:移动多少个字节
起始点:表示从何处开始计数,规定的有三个起点:
文件首: SEEK_SET
文件尾: SEEK_END
当前位置: SEEK_CUR
如:fseek(fp,-5,SEEK_CUR);将文件指针从当前位置向前移动5个字节处
6.文件检测函数
1) 文件结束检测函数feof函数
调用格式:
feof(文件指针);
功能:判断文件是否处于文件结束位置,如文件结束,则返回值为1,否则为0。
2) 读写文件出错检测函数
ferror函数调用格式:
ferror(文件指针);
功能:检查文件在用各种输入输出函数进行读写时是否出错。如ferror返回值为0表示未出错,否则表示有错。
3) 文件出错标志和文件结束标志置0函数
clearerr函数调用格式:
clearerr(文件指针);
功能:本函数用于清除出错标志和文件结束标志,使它们为0值。
6.库函数 (略)