14.2.6 文件访问机制

    前面已经提及,文件访问分为打开文件、读写文件和关闭文件3个步骤,I/O库中提供的文件访问函数很多,本书不可能逐个详细介绍,以下将常用函数简要列出。

    (1)fclose函数:关闭一个流的函数。

    原形:int fclose(FILE*fp);。

    使用方式:fclose(文件指针名);,其中文件指针名=fopen();。

    功能:关闭指定的流fp,断开与其所有连接,并清除所有与之相联的缓冲区,释放系统分配的缓冲区,但由setbuf设置的缓冲区不能自动释放。

    返回值:0(成功);,EOF(失败)。

    (2)fcloseall函数:关闭打开的流的函数。

    原形:int fcloseall(void);。

    功能:关闭所有打开的流,由stdin、stdout、stdprn、stderr和stdaux设置的流除外。

    返回值:关闭流的总数。如果发现错误则返回EOF。

    (3)fgets函数:从流中读取若干字符到C风格字符串中的函数。

    原形:charfgets(char s[],int n,FILEstream);。

    使用格式:fgets(字符串指针,字符个数,文件指针)。

    功能:从输入流stream中读入字符存到s串中。当读了n-1个字符或遇到换行符时,函数停止读过程,读入的最后一个字符后面加一个空字符。

    返回值:成功时返回字符串参数s,出错或遇到文件结束时,返回NULL。

    (4)fopen函数:打开一个流函数。

    原形:FILEfopen(const charfilename,const char*mode);。

    功能:打开用filename指定的文件,并使其与一个流相联,可用mode如下表14.3所示。

    14.2.6 文件访问机制 - 图1

    注意

    “a”和“a+”在对待文件尾标记EOF时有细微不同,a模式不会将原文件的EOF移除,而a+模式会移除原文件中的EOF。

    还可以使用b(代表binary,二进制)或t(代表text,文本)指定文件的打开方式是文本方式(ASCII)还是二进制形式,b和t一定要放在r、w和a之后,+号之前,否则,如果将b和t作为前缀,fopen函数同样会运行失败,返回NULL。

    返回值:指明流的指针(成功时)或NULL(失败时)。

    注意

    需先定义FILE*文件指针名,“文件名”若用argv[1]代替,则可使用命令行形式指定文件名。

    (5)fprintf函数:传送输出到一个流中的函数。

    原形:int fprintf(FILEstream,const charformat[,argument,……]);。

    功能:向文件指针指向的文件输出ASCII代码,以及向显示器输出错误信息。

    使用形式:fprintf(文件指针,控制字符串,参数表);和fprintf(stderr,"错误信息");。

    返回值:成功则返回输出的字节数,失败则返回EOF。

    (6)fscanf函数:格式化输入函数。

    原形:int fscanf(FILEstream,const charformat[,address,……]);。

    功能:从一个流中扫描输入字段,一次扫描一个字符,每个输入字段根据format所指格式指示符格式化后,把输入字段存在format后面由地址参数给出的位置上。

    (7)fseek函数:移动文件指针函数。

    原形:int fseek(FILE*stream,long offset,int whence);。

    功能:强制一个文件的位置指针指向某个特定的位置(甚至超出文件的尾部)。定义FILE*文件指针名;起点whence取值有以下3种情况。

    ❑0或SEEK_SET(表示文件开头)

    ❑1或SEEK_CUR(表示当前位置)

    ❑2或SEEK_END(表示文件尾端)

    返回值:0表示成功,非0值表示失败。

    (8)fputs函数:向文件输出C风格字符串的函数。

    原形:int fputs(const chars,FILEfp);。

    功能:把以空字符结尾的串s复制到fp相关的文件中,但空字符除外(注意与puts函数的区别)。

    返回值:成功调用返回非负值,否则返回EOF。

    (9)getc函数:从流中取一个字符的函数。

    原形:int getc(FILE*stream);。

    功能:返回输入流stream中一个字符,移动文件指针使之指向下一个字符。

    返回值:正常情况下能够读取到代码值,读到文件尾或出错时返回EOF。

    注意

    需定义char字符变量和FILE*文件指针。

    (10)getchar函数:从stdin流中读取一个字符的函数。

    原形:int getchar(void);。

    功能:将键盘上输入的单个字符的值(ASC Ⅱ码)回车后赋给字符型变量。

    注意

    getchar函数相当于getc(stdin)。

    (11)gets函数:读取到一个C风格字符串的函数。

    原形:chargets(chars);。

    功能:从标准输入流stdin中读取一C风格字符串的函数。

    返回值:如果写入了字符,返回s,否则返回NULL。

    (12)fputc函数:输出一个字符到文件的函数。

    原形:int fputc(int c,FILE*fp);。

    功能:将参数c转换成unsigned char,写入fp相关的文件中。

    返回值:调用成功,返回(int)(unsigned char)c,否则返回EOF。

    (13)putchar函数:输出一个字符到stdout(标准输出)的函数。

    原形:int putchar(int c);。

    功能:在stdout上输出字符c。

    返回值:成功返回字符c,失败返回EOF。

    注意

    putchar(c)等价于fput(c,stdout)。

    (14)puts函数:输出一C风格字符串到stdout(标准输出)的函数。

    原形:int puts(const char*s);。

    功能:把以空字符结尾的串s赋值到标准输出流中,但不复制空字符,而是写入一个换行符。

    返回值:如果调用成功,函数返回一个非负值,否则返回EOF。

    (15)remove函数:删除一个文件的函数。

    原形:int remove(const char*filename);。

    功能:删除一个文件。

    返回值:0(成功);-1(失败)。

    简要地对一些基本函数进行了介绍后,来看以下示例代码14.5所示。

    代码14.5 高层I/O文件操作FileIO


    <————————————文件名:example1405.cpp———————————————> 01 #include<cstdio> 02 #include<cstdlib> 03 int main() 04 { 05 FILEfp1=NULL,fp2=NULL;//创建指向FILE结构的指针 06 char sz[100]; 07 printf("请输入一段字符:\n"); 08 scanf("%s",sz);//等价于sscanf(sz,"%z"); 09 fp1=fopen("out. txt","w+");//生成out.txt用于读写 10 if(fp1==NULL) 11 exit(1);//如果流创建失败,退出 12 fprintf(fp1,"%s",sz);//将sz的内容写入fp1指向的文件中 13 fseek(fp1,0,SEEK_SET);//移动到fp1指向的文件头部 14 fp2=fopen("trans. txt","wt");//生成trans.txt,用于写 15 if(fp2==NULL) 16 exit(1); 17 int c=0; 18 while((c=getc(fp1))!=EOF)//从文件开始到结束EOF 19 { 20 fputc(toupper(c),fp2);//转换成大写形式写出 21 fputc('',fp2);//写出一个空格 22 } 23 fclose(fp2);//关闭流 24 fclose(fp1); 25 return 0; 26 }

    输出结果如下所示。


    请输入一段字符: Hello,China(用户输入)此时,在文件夹下多了两个txt文件,out.txt和trans.txt,其中的内容分别如下所示。 out.txt:Hello,China trans.txt:H E L L O,C H I N A

    【代码解析】代码第5行首先声明了两个指向FILE结构的指针fp1和fp2,利用fopen函数使fp1和fp2分别指向两个文件流,首先提示用户输入一个字符串,存储在char型数组sz中,而后将sz存储到fp1指向的文件out.txt中,最后将out.txt中的字符逐个大写后复制到fp2指向的文件trans.txt中。

    需要说明第一toupper(char)函数,定义在头文件<cstdlib>中,是用于返回一个字符的大写形式,第二exit函数,在第2章中已经进行过介绍在此不再赘述。