C语言:随笔11--文件操作

 文件通常是驻留在外部介质(如磁盘等)上的,在使用时才调入内存中来。

文件的分类:按数据的组织形式:

(1)ASCII文件(文本文件):每一个字节放一个ASCII代码。

(2)二进制文件:把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放。

例如整数10000D(D表示10进制)在内存中的存储形式以及分别按照ASCII形式和二进制形式输出如下图所示:

ASCII的1对应的十六进制是32H(H表示16进制),十进制是49,二进制是110001。

ASCII文件便于对字符进行逐个处理,也便于输出字符。但是一般占存储空间较多,而且要花费转换时间(因为内存是直接跟CPU交换的,又要用ASCII来存储,所以二进制必须要有一个转换为ASCII。(因为CPU只读二进制))。(比如上边是一个字符一个字符处理的,把1当作一个字符,0当作一个字符,共四个0分别当作4个字符来处理) 

二进制文件可以节省外存空间和转换时间,但是一个字节并不对应一个字符,不能直接输出字符形式(因为要把它转化为ASCII再来输出)。(因为我们显示一个东西出来都是按照ASCII码显示的,我们输入一个东西都是按照ASCII码形式输入的,然后它在转化为二进制) 

缓冲文件系统和非缓冲文件系统。

C语言对文件的读写都是通过库函数(缓冲文件系统)来实现的。

一、文件的打开与关闭

(1)文件型指针变量

FILE *fp;//FILE是一个结构,是一个FILE(文件型)结构。FILE是一个文件的名称。用这个结构来定义一个指针,这个指针就是指向一个文件。
 //fp是一个指向FILE类型结构体的指针变量(那么什么是一个FILE类型结构体呢?)。

FILE类型结构体是定义在我们的标准输入输出里面头文件stdio.h,

  

//先定义一个input/outputbuffer(缓冲区)结构,然后再用typedef类型重命名将iobuf这个结构命名为FILE。那么我用FILE来定义一个fp(FILE *fP;)就相当于struct _iobuf *fp;这样我们的fp指针就指向上边的结构的。这个指针我们需要往里边填充类似于这个结构的东西。 

我们使fp指向某一个文件的结构体变量,从而通过该结构体变量中的文件信息能够访问该文件。

如果有n个文件,一般应设n个指针变量,使他们分别指向n个文件,以实现对文件的访问。

怎么使用呢?我们就可以用FILE类型的数组:

FILE f[5];定义了一个结构体数组f,他有5个元素,可以用来存放5个文件的信息。

(1)文件的打开(fopen函数)

//函数调用://定义一个指向FILE结构体的指针fp
FILE *fp;
fp=fopen(文件名,使用文件方式);//将这个指针的值赋予什么呢?用fopen打开,其实用fopen打开他之后它就会填充这个结局体, 然后把他赋给fp,fp指向他。
//注意:(1)需要打开的文件名,也就是准备访问的文件的名字。(要加上他的路径是在D盘还是F盘等)
//注意:(2)使用文件的方式(“读”还是“写”等)具体的打开方式见下, 
//注意:(3)让哪一个指针变量指向被打开的文件。(我们这里使用的是fp指向,要保证有指向)

文件的使用方式:

“ab”以这种方式的话打开的时候指针就是指向了文件的末尾。

对于文件使用方式有以下说明:

  • 凡用“r”打开一个文件时,该文件必须已经存在,且只能从该文件读出。(如果文件不存在就无法打开,只能返回一个空指针,NULL指针,就指不到地方去了。)
  • 用“w”打开文件只能向该文件写入。若打开的文件不存在,则以指定的文件名建立该文件。若打开的文件已经存在,则该文件删去,重新建立一个新文件。
  • 若要想一个已存在的文件追加新的信息,只能用“a”方式打开文件。但此时该文件必须是存在的,否则将会出错。
  • 在打开一个文件时,如果出错,fopen将返回一个空指针NULL。在程序中可以用这一信息来判别是否完成打开文件的工作,并作相应的处理。
  • 把一个文本文件读入内存时,要将ASCII码转换成二进制码,而把文件以文本方式写入磁盘时,也要把二进制码转换成ASCII码,因此文本文件的读写要花费较多的转换时间。对二进制文件的读写不存在这种转换。

示例代码:

#include<stdio.h>
#include<stdlib.h>
void main()
{
    FILE *fp;
    if(!(fp=fopen("F:\\1.txt","rb")))//注意要“\”  //b是二进制的形式
    {
        printf("Can not open F:\\1 file!\n");
        system("pause");//让系统暂停在这,接受用户的操作
    }
    else
    {
        printf("Open success!\n");
    }
}

(2)文件的关闭

文件只要打开了他就要映射到内存上去了,那如果我没没有把他给关闭,没有把这个指针给断开的话,它会一直占着那个空间。
 

//函数调用:
fclose(文件指针);
//函数功能:使文件指针变量不再指向该文件,也就是文件指针变量与文件“脱钩”,此后不饿能再通过该指针对原来与其相联系的文件进行读写操作。
//返回值:关闭成功返回值为0;否则返回EOF在C语言中定义为-1.

读就是把文件的内容读出来,读取到缓冲区。写就是把新的内容写入文件中。

C中有多种的文件读写函数:

//字符读写函数:fgetc和fputc//其中f是file的缩写,c是char的缩写
//字符串读写函数:fgets和fputs 。
//数据块读写函数:freed和fwrite。
//格式化读写函数:fscanf和fprintf//就是按照一定的格式,有点像我们的scdnf和printf,前边加上f表示他是关于文件的。
//以上函数都要包含头文件stdio.h。

(1)字符输入输出函数(fputc()和fgetc())

//fputc()函数调用:
fputc(ch,fp);//fp是一个指针
//函数功能:将字符(ch的值)输出到fp所指向的文件中去。(比如字符‘a’他的ASCII码是65,那就把65输入进去,因为我们是纯文本输入,是输入ASCII的)
//用写或者读写方式打开一个已存在的文件时将清除原有的文件内容,写入字符从文件首开始。如需保留原有文件内容,希望写入的字符以文件末开始存放,必须以追加方式打开文件。被写入的文件若不存在,则创建该文件。
//每写入一个字符,文件内部位置指针向后移动一个字节。
//fputc函数有一个返回值,如写入成功则返回写入的字符,否则返回一个EOF。可以用来判断写入是否成功。

//示例文件的写入:
#include<stdio.h>
#include<stdlib.h>
void main()
{  
   FILE *fp;//指针fp指向FILE结构,也就是说指针指向的内存它是以FILE结构来读取的
   char ch,filename[20];
   printf("Please input the filename you want to write:");
   scanf("%s",filename);//filename是数组名表示首地址//表示将要创建的文件的名称
   if(!(fp=fopen(filename,"wt+")));//wt+表示读写打开或建立一个文本文件,允许读和写
   {//打开错误就是返回NULL,那么!NULL就是1,进入if语句,输出不能打开文件
       printf("Cannot open the file!\n");
       exit(0);//终止程序
   }
   printf("Please input the sentences you want to write:");
   ch=getchar();
   ch=getchar();//有两个getchar()函数?(如果只写一个ch=getchar();语句写入的文件就会在内部的一行出现一个空行?为什么?)
   while(ch!=EOF)//如果输入的不是EOF //EOF一般是我们ASCII编码的文件的结束标志,怎么输入EOF呢?(EOF输入是ctl+z组合键)
   {
      fputc(ch,fp);
      ch=getchar();//再次接收来自键盘的输入,然后继续循环把他给写入,直到我们输入EOF
   }
   fclose(fp);//关掉文件
}
//fgetc()函数调用:
ch=fgetc(fp);
//函数功能:其意义是从打开的文件fp中读取一个字符并送入ch中。
//在fgetc函数调用中,读取的文件必须是以读或读写方式打开。
//在文件内部有一个位置指针。用来指向文件当前读写子节。(因为我们读取一个之后等一下要读取第二个,指针要指向第二个你才能读取,如果一直指向第一个的话你就只能永远读取的第一个。所以有一个指针你读了第一个之后他会自动指向第二个。有一个这样的机制 )
//在文件打开时,该文件总是指向文件的第一个子节。使用fgetc函数后,该位置指针将向后移动一个字节。因此连续多次使用fgetc函数,读取多个字符。
//应注意文件指针(FILE *fp)和文件内部的位置指针(是windows系统内部自动匹配自动调用的我们不需要管)不是一回事。
//文件指针是指向整个文件的,须在程序中定义说明,只要不重新赋值,文件指针的值是不变的。
//文件内部的位置指针用以指示文件内部的当前读写位置,每读写一次,该指针均向后移动,它不需要在程序中定义说明,而是由系统自动设置的。 

//示例文件的写入:
#include<stdio.h>
#include<stdlib.h>
void main()
{  
   FILE *fp;//指针fp指向FILE结构,也就是说指针指向的内存它是以FILE结构来读取的
   char ch,filename[20];
   printf("Please input the filename you want to write:");
   scanf("%s",filename);//filename是数组名表示首地址//表示将要创建的文件的名称
   if(!(fp=fopen(filename,"r")));
   {
       printf("Cannot open the file!\n");
       exit(0);//终止程序
   }
   while(ch!=EOF)
   {
      ch=fgetc(fp);//读出的字符保存在ch中
      putchar(ch);//把ch显示在屏幕上 
   }
   fclose(fp);//关掉文件
}

//补充1 :
//从一个文本文件顺序读入字符并显示在屏幕上。
ch=fgetc(fp);
while(ch!=EOF)
{
    putchar(ch);
    ch=fgetc(fp);
}
//注意:EOF不是可输出字符,因此不能在屏幕上显示。由于字符的ASCII码不可能出现-1(ASCII码是从0开始),因此EOF定义为-1是合适的。当读入的字符值等于-1时,表示读入的已不是正常的字符而是文件结束符。
//补充2:
//从一个二进制文件顺序读入字符 ;(就不是-1的问题了,因为二进制文件你想什么数都可以,因为CPU处理的是二进制文件,没有任何约定,任何数都是二进制文件,那么它就没有一个EOF我们可以定了,那么我们怎么知道它结束了呢?我们用一个函数feof(),eof就是end of file的缩写,feof()是文件结束的一个函数)
while(!feof(fp))//feof()函数作用:Tests for end-of-file on a stream.测试是否文件的结尾
{
    ch=fget(fp);
}
//因此ANSIC提供一个feof()函数来判断文件是否真的结束。如果文件结束,函数feof(fp)的值为1(真);否则为0(假)。这个也适用于文本文件的读取。//但是在二进制文件中不能使用EOF(因为二进制文件中有-1这个数)。

编写一个二进制文件的读取和写入:(图片、文件合成器)

在图片捆绑了一个可执行文件(.rar)(一个jpg图片更改后缀名为rar,就会生成一个压缩文件。将一个jpg图片加进来一个.rar文件,是两者的合成版本 )

#include<stdio.h>
#include<stdlib.h>
void main()
{
    FILE *f_pic,*f_file,*f_finish;//需要三个指针文件,打开两个,再写入一个新的
    char ch,pic_name[20],file_name[20],finish_name[20]; //声明变量
    printf("请输入需要合成的图片和文件名称:\n");
    printf("图片:");
    scanf("%s",pic_name);//w文件的名称是什么?字符串,必须把它把他赋值到一个变量里边去。//所以上边要声明变量
    printf("文件:");
    scanf("%s",file_name);
    printf("生成为:");
    scanf("%s",finish_name);
    //打开pic1
    if(!(f_pic=fopen(pic_name,"rb")))//以二进制读写方式打开,并存放在f_pic这个文件指针里
    {
        printf("Cannot open the picture %s",pic_name);//打不开
        return;
    }
    //打开file2
    if(!(f_file=fopen(file_name,"rb")))//以二进制读写方式打开,并存放在f_pic这个文件指针里
    {
        printf("Cannot open the picture %s",file_name);//打不开
        return;
    }
    //打开3第三个是要写入的,是原本不存在的,我们新建的。//我们将要生成的
    if(!(f_finish=fopen(finish_name,"wb")))//以二进制读写方式打开,并存放在f_pic这个文件指针里
    {
        printf("Cannot open the file %s",finish_name);//打不开 
        return;
    }
    //先把打开的1读出来然后写进3。写完之后再把2的内容写进3.
    //我们要写一个文件,必须要判断文件内部指针有没有指向结尾,才知道什么时间结束,所以使用内置函数feof()//函数返回值如果返回0表示现在的位置不是文件尾部,返回非0说明是文件的结尾了。
    while(!feof(f_pic))
    {
        ch=fgetc(f_pic);//上边定义的ch是用来暂时存放读取的那个数据//fgetc()这个函数就会读取f_pic这个文件里面的一个字节,然后把他当作返回值赋值给ch.
        fputc(ch,f_finish); //然后将ch给了finish_name这个文件.(参数1:需要写入的字符;参数2:需要写入的文件的指针)
    }
    //进行到文件尾部就会退出while,所以我们要关掉这个文件指针
    fclose(f_pic);
    //现在把压缩文件接到后边去(当要接一个文件后边继续添加内容时:(就比如上边已经拷贝进去一个了要接着在文件中在后边再添加一个)这时这里的文件内部指针不用去管它,当他拷贝到文件后面呢最后一个位置时他的指针现在是指向文件最后一个格的(也就是最后一个字节的))
    while(!feof(f_file))
    {
        ch=fgetc(f_file);//上边定义的ch是用来暂时存放读取的那个数据//fgetc()这个函数就会读取f_pic这个文件里面的一个字节,然后把他当作返回值赋值给ch.
        fputc(ch,f_finish); //然后将ch给了finish_name这个文件.(参数1:需要写入的字符;参数2:需要写入的文件的指针)
    }
    //进行到文件尾部就会退出while,所以我们要关掉这个文件指针
    fclose(f_file);
    fclose(f_finish);//都关掉
    system("pause");

}

-----上边是一个个字节读取现在字符串的读写函数:fgets和fputs

字符串的输入输出函数fputs()和fgets()。

//fgets()函数
//函数调用形式如:fgets(str,n,fp);//有三个参数
//函数作用:从fp所指的文件中读出n-1个字符送入字符数组str中,因为在最后加一个'\0'(字符串的标志结尾0,C语言规定字符串的结尾是以\0来标志的,其他语言有所不同).
//函数返回值:返回str的首地址。

读出示例:

//有一个1.txt文件,我想把它读出来,然后打印到屏幕上
#include<stdio.h>
#include<stdlib.h>
#define LEN 11//用宏定义方便后期改字节,不用一个个去改
void main()
{
    FILE *fp;
    char buffer[LEN];//定义一个字符缓冲区,该字符缓冲区有LEN这么长,也就是下边可以读取LEN-1个字节,因为最后一个字节他会自动加上‘\0’,表示字符串结束。
    if(!fp=fopen("1.txt","rt"))//fp指向的是1.txt这个文件 
    {
       printf("\nCannot open file strike any key exit!");
       exit(1);
    }
    fgets(buffer,LEN,fp);//从fp拿到LEN-1这么长的东西,给了buffer这个缓冲区
    printf("%s\n",buffer);//把buffer缓冲区的内容以字符串的形式打印出来 
    fclose(fp);//关闭

}

fputs()字符串的写入一个文件:

//fputs函数
//函数调用方式:fputs("FISHC",fp);//将FISHC输入到我们fp所指向的这个文件中
//函数作用:把字符串"FISHC"写入fp所指的文件之中。
//函数返回值:输入成功的话,返回值为0;输入失败的话,返回值时EOF。

写入函数示例:

//从屏幕上输入一个字符串,然后程序截取这个字符串,把他给放到这个文件的结尾处
#include<stdio.h>
#include<stdlib.h>
#define LEN 20
void main()
{
    FILE *fp;
    char ch,buffer[LEN];//建立20个长度的缓冲区用来放入从屏幕上输入的字符串
    if(!fp=fopen("1.txt","at+"))//这里以“at+”的形式写入,粘贴在后面(意思就是将1.txt这个文件打开,将内部的文件指针指向了结尾处,然后我们从这里写入的话是从文件的结尾开始写)
    {
       printf("\nCannot open file strike any key exit!");
       exit(1);
    }
    printf("Please input a string:\n",buffer);
    //正常做法输入字符串用scanf()
    //scanf("%s",buffer);//接收一个字符串,然后把他存在buffer这个缓冲区里面
    //因为scanf这个函数使用%s接收字符串的话,当他遇到空格和回车的时候,他都是自动声明这个接收已经结束了,后边的就不再接收了。
   //前边讲过fgets()是从文件中获取字符串,那为什么这里可以从我们的键盘获取?(因为我们的键盘实际上也是夜歌特殊的文件,叫做stdin文件,标准输入文件,我们从键盘上输入的东西会放入stdin这个文件,作为一个缓冲区存放到里面去,那么我们就从stdin这里面读就可以了)
    fgets(buffer,LEN,stdin);//写入的话用fgets()来写,而不用scanf().//为什么不用scanf()?stdin又是啥?
    fputs(buffer,fp);//把buffer写入到fp这个文件里面去(fputc如果是c的话参数Buffer就得表示一个字节,fputs如果是s的话参数buffer就得是一个字符串,但是fp都是一个指向的文件。)
    rewind(fp);//(写完之后)重新定义文件内部指针去指向到开头处(这样是比较优良的做法,不这样做也没问题)(这里之所以这么做,因为我还想把他再打印出来,这样可以让我们看到整个文件写进去之后有所改变)
    ch=fgetc(fp);
    while(ch!=EOF)//这里使用一个循环,只要他不是文件结尾他就会把它输出到屏幕上
    {
        putchar(ch);
        ch=fgetc(fp);
    }
    printf("\n");
    fclose(fp);//关闭

}

数据块读写函数fread()和fwrite()。//可以使用fread和fwrite来进行数据的操作。

什么是数据块呢?刚才是一串一串的读,我们现在是一块一块的读。

//函数调用:
//fread(buffer,size,count,fp);
//fwrite(buffer,size,coubt,fp);
//参数说明:
//buffer:是一个指针。(对fread来说,他是一个读入数据的存放地址;对fwrite来说,是要输出数据的地址(均指起始地址))(是一个缓冲区)
//size要读写的字节数。(这个块非常灵活,你可以当他是一个字节一个字节或者10个字节一个块也行)
//count:要进行读写多少个size字节的数据项。(次数/个数。比如我的size是10个字节,count是2,那就是你读取了20个字节。(就是以10个字节分为1块,读取count2个块))
//fp:是一个文件的指针。

示例:如下结构:

struct  student_type
{   
   char name[20];   
   int num;
   int age;
   char addr[30];
}stud[40];//定义了40个学生,每个学生都是一个这样的结构

//读取方式
for(I=0;i<40;i++)
{
    fread(&stud[i],sizeof(struct student_type),1,fp);//声明要读取到std这个变量里边去,每次读取的大小是sizeof,每次读一次就是一个学生,从fp这个文件
}
//写入也一样每次写入一个学生的内容(你如果按照原来一个字节一个字节的来写,那么各个学生就会打乱了)
for(I=0;i<40,i++)
{
    fwrite(&stud[i],sizeof(struct student-type),1,fp);
}

要求:从键盘输入4个学生的有关数据,然后以二进制的格式存储到磁盘文件。

#include<stdio.h>
#include<stdlib.h>
define SIZE 4;
struct student
{
   char name[10];   
   int num;
   int age;
   char addr[15];
}stu[SIZE];
void save()
{
   FILE *fp;
   int i;
   if(!(fp=fopen("student-list","wb")))//student-list是一个二进制文件
   {
       printf("Cannot open the file!\n"); 
       return;  
   }
   for(i=0;i<size;i++)
   {
       if(fwrite(&stu[i],sizeof(struct studet),1,fp)!=1)
       {
          printf("File write error!\n");
          fclose(fp);
       }
       
   }
}
//写一个load()函数将该文件读取并显示
void load()
{
    FILE *fp;
    int i;
    if(!(fp=fopen("student-list","r")))//student-list是一个二进制文件
    {
       printf("Cannot open the file!\n"); 
       return;  
    }
    //读取方式
    for(i=0;i<40;i++)
    {
       fread(&stud[i],sizeof(struct student),1,fp);
     //printf("%s,%d,%d,%s",&stud[i].name,&stud[i].num,&stud[i].age,&stud[i].address);//不需要这一行(因为fread带显示)
       fclose(fp);
    }
void main()
{  
   int i;
   printf("Please input student's name,num,age,address:\n");
   for(i=0;i<40,i++)
   {
      scanf("%s %d %d %s",stud[i].name,&stud[i].num,&stud[i].age,&stud[i].address); 
   }//此时输入的都是输入到缓冲区文件里边去
   save();
   load();
}

-----格式化读写函数(fprintf()和fscanf())//(跟平时使用的printf和scanf是一样的,前边多了一个f表示是对文件的读写)(如果没有f的话它是对我们的键盘还有显示器,写入/写进到显示器就是输出数来,从键盘上读取字符。)

 //函数调用:
//fprintf(文件指针,格式字符串,输出表列);
//fscanf(文件指针,格式字符串,输出表列);
//函数功能:从磁盘文件中按照格式读入或输出字符。
//例如:
//fprintf(fp,"%d,%6.2f",i,t);// “%6.2f”表示6位的浮点数,两位的小数点,然后存放在这个t这个浮点型的变量里面。
//fscanf(fp,"%d,%f",&i,&t);

-----顺序读写和随机读写

顺序读写:以上将的都是顺序读写(就是从文件打开,从头开始往后这么写进去/或者读出来 )

位置指针按字节位置顺序移动。

随机读写:读写完一个字符(字节)后,并不一定要读写其后续的字符(字节),而可以读写文件中任意位置上所需要的字符(字节)(这个位置我们是可以控制它的,那么我们就必须要学一个fseek函数)

fseek函数(一般用于二进制的文件比较多)(作用是改变文件的位置指针)

//函数功能:
//改变文件的位置指针(这个函数主要是改变文件内部的指针,改变它我们就可以跳跃性的读写,比如说读了第一个字符之后我就用fseek把他跳跃到第以00个字符,之后我就从第100个字符开始读了)
//函数调用格式:
//fseek(文件类型指针,位移量,起始点);
//第三个参数:起始点:
//文件开头  SEEK_SET  0//如果起始点设置的是0的话,他的宏定义是SEEK_SET,他是从文件的开头位置开始读的
//文件当前位置  SEEK_CUR   1//如果起始位置设为1的话他是从文件的当前的文件指针的位置,因为我们每读过一次,他的文件指针都会向后移一格
//文件末尾   SEEK_END    2//如果是2的话,宏定义是SEEK_END的话,他是标志着从文件的末尾开始读取
//第二个参数:位移量
//位移量:以起始点为基点,向前移动的字节数(以这个起始点标志的位置以后的偏移量等于多少,就是这个位移量一般都是以long型的形式存在的)
//例如:fseek(fp,100L,0);//将位置指针移到离文件头100格字节处//L表示long型
//fseek(fp,50L,1);//将位置指针移到离当前位置50个字节处(这个当前位置就不一定是文件头了,说不定在之前已经read过多少次了,读过多少个字节了,那就从你现在接着的地方开始,50个字节处)
//fseek(fp,50L,2);//将文件指针从文件末尾处向后退50个字节(因为已经是最末尾了,不能再前进了,所以表示向后退) 
//fseek(fp,i*sizeof(struct stu),0)//这样的话我们就要通过表达式计算了,i是个变量

例子:在学生文件stu_list中读出第二个学生的数据

struct student
{
   char name[10];
   int num;
   int age;
   char addr[15];
}boy;//student结构中的Boy变量
void main()
{
   FILE *fp;
   int i;//用于定位i个结构
   if(!(fp=fopen(student_list,"r")))
   {
       printf("Cannot open the file!\n");
       return;
   }
   rewind(fp);//设置内部文件指针指向头(也就是重置了文件指针)
   fseek(fp,i*sizeof(struct student),0);//这个时候文件内部指针已经指向了第二个学生的开头位置
   fread(&boy,sizeof(struct student),1,fp);//&boy第一个传给他缓冲区就是存放的一个地址。然后sizeof(struct student)存放多少(一块读取多少),1读取一块就行了,fp指向文件
   printf("name\tnumber  age   addr\n");//打印出来
   printf("%s\t%5d   %7d    %s\n",boy.name,boy.num,boy.age,boy.addr);
   fclose(fp);
   system("pause");
}

ftell函数

//函数作用:得到流式文件(就是我们的文件流)中当前位置,用相对于文件开头的位移量来表示。
//返回值:返回当前位置(就是当前位置离文件开头的偏移量),出错时返回-1L,在文件头就是返回0,在文件头一个字节的地方他就是返回1。
//应用举例;
i=ftell(fp);
if(i==-1L)
{
   printf("erroe\n");
}

---出错的检测ferror函数(对于检测输入输出会不会出现错误)

//ferror函数
//调用形式:
ferror(fp);
//返回值:返回0,表示未出错;返回非0,表示出错。
//注意:在调用一个输入输出函数后立即检查ferror函数的值,否则信息会丢失(就是会被下一个覆盖掉)。再指向fopen函数时,ferror函数的初始值自动置为0(因为刚刚打开,打开成功的话初始值是设为0的)。

 ----clearerr函数

//调用形式:
clearer(fp);
//函数作用:使文件错误标志和文件结束标志置为0.
//注意:只要出现错误标志,就一直保留,直到对同一文件调用clearerr函数或rewind函数,或任何其他一个输入输出函数。

总结:

   

猜你喜欢

转载自blog.csdn.net/m0_37957160/article/details/108750862