在C语言中,对文件的操作都通过标准库中的函数或宏来进行。标准库不是C语言本身的构成部分,但是支持标准C的实现都会提供该函数库中的函数声明、类型以及宏定义。比如,与文件操作相关的函数都定义在输入输出头文件<stdio.h>中。
流、缓存和文件
流(stream)不是缓存,也不等于文件。流是一种逻辑的、与设备无关的操纵多种外设方式,它把数据输入输出的操作对象(如磁盘文件或是物理设备的打印机、显示器、键盘等)都抽象化为一种“流”而不管其具体结构,这样涉及到流的操作函数都可用于各种对象,提高了编程的通用性。《C程序设计语言》中说“流是与磁盘或其他外围设备关联的数据的源或目的地,打开一个流,将把该流与一个文件或设备连接起来,关闭流将断开这种连接”。从代码的实现上来看,一个流可以由一个FILE结构来描述,而FILE结构里包含了指向缓冲区的指针和文件描述符,打开一个流时它通过指向缓冲区的指针和文件描述符来和缓存与文件(或设备)关联。更多的介绍还可以看这里和这里。
文件操作函数
FILE *fopen(const char *filename, const char *mode)
fopen函数打开filename指定的文件,并返回一个与之相关联的流。如果打开操作失败,则返回NULL。
int fclose(FILE *stream)
fclose函数将所有未写入的数据写入stream中,丢弃缓冲区中的所有未读输入数据,并释放自动分配的全部缓冲区,最后关闭流。若出错则返回EOF,否则返回0。
int remove(const char *filename)
remove函数删除filename指定的文件,这样,后续试图打开该文件的操作将失败。如果删除操作失败,则返回一个非0值。
int rename(const char *oldname, const char *newname)
rename函数修改文件的名字。如果操作失败,则返回一个非0值。
int setvbuf(FILE *stream, char *buf, int mode, size_t size)
void setbuf(FILE *stream, char *buf)
setvbuf/setbuf函数控制流stream的缓冲。
格式化输入/输出
int fprintf(FILE *stream, const char *format, …)
fprintf函数按照format说明的格式对输出进行转换,并写到stream流中。返回值是实际写入的字符数。若出错则返回一个负值。
int fscanf(FILE *stream, const char *format, …)
fscanf函数根据格式串format从流stream中读取输入,并把转换后的值赋值给后续各个参数,其中的每个参数都必须是一个指针。当格式串format用完时,函数返回。如果到达文件的末尾或在转换输入前出错,该函数返回EOF;否则,返回实际被转换并赋值的输入项的数目。
字符输入/输出函数
int fgetc(FILE *stream)
fgetc函数返回stream流的下一个字符,返回类型为unsigned char(被转换为int类型)。如果到达文件末尾或发生错误,则返回EOF。
char *fgets(char *s, int n, FILE *stream)
fgets函数最多将下n-1个字符读入到数组s中。当遇到换行符时,把换行符读入到数字s中,读取过程终止。数组s以’\0′结尾。fgets函数返回数组s。如果到达文件的末尾或发生错误,则返回NULL。
int fputc(int c, FILE *stream)
fputc函数把字符c(转换为unsigned char类型)输出到流stream中。它返回写入的字符,若出错则返回EOF。
int fputs(const char *s, FILE *stream)
fputs函数把字符串s(不包含字符’\n’)输出到流stream中;它返回一个非负值,若出错则返回EOF。
int getc(FILE *stream)
getc函数等价于fgetc,所不同的是,当getc函数定义为宏时,它可能多次计算stream的值。
int putc(int c, FILE *stream)
putc函数等价于fputc,所不同的是,当putc函数定义为宏时,它可能多次计算stream的值。
直接输入/输出函数
size_t fread(void *ptr, size_t size, size_t nobj, FILE *stream)
fread函数从流stream中读取最多nobj个长度为size的对象,并保存到ptr指向的数组中。它返回读取的对象数目,此返回值可能小于nobj。必须通过函数feof和ferror获得结果执行状态。
size_t fwrite(const void *ptr, size_t size, size_t nobj, FILE *stream)
fwrite函数从ptr指向的数组中读取nobj个长度为size的对象,并输出到流stream中。它返回输出的对象数目。如果发生错误,返回值会小于nobj的值。
文件定位函数
int fseek(FILE *stream, long offset, int origin)
fseek函数设置流stream的文件位置,后续的读写操作将从新位置开始。对于二进制文件,此位置被设置为从origin开始的第offset个字符处。origin的值可以为SEEK_SET(文件开始出)、SEEK_CUR(当前位置)或SEEK_END(文件结束处)。对于文本流,offset必须设置为0,或者是由函数ftell返回的值(此时origin的值必须是SEEK_SET)。fseek函数在出错时返回一个非0值。
long ftell(FILE *stream)
ftell函数返回stream流的当前文件位置,出错时该函数返回-1L。
void rewind(FILE *stream)
rewind(fp)函数等价于语句fseek(fp, 0L, SEEK_SET); clearerr(fp)的执行结果。
int fgetpos(FILE *stream, fpos_t *ptr)
fgetpos函数把stream流的当前位置记录在*ptr中,供随后的fsetpos函数调用使用。若出错则返回一个非0值。
int fsetpos(FILE *stream, const fpos_t *ptr)
fsetpos函数将流stream的当前位置设置为fgetpos记录在*ptr中的位置。若出错则返回一个非0值。
错误处理函数
当发生错误或到达文件末尾时,标准库中的许多函数都会设置状态指示符。这些状态指示符可被显式地设置和测试。另外,整数表达式errno(在
void clearerr(FILE *stream)
clearerr函数清除与流stream相关的文件结束符和错误指示符。
int feof(FILE *stream)
如果设置了与stream流相关的文件结束指示符,feof函数将返回一个非0值。
int ferror(FILE *stream)
如果设置了与stream流相关的错误指示符,ferror函数将返回一个非0值。
void perror(const char *s)
perror(s)函数打印字符串s以及与errno中整型值相应的错误信息,错误信息的具体内容于具体实现有关。该函数的功能类似于执行下列语句:
fprintf(stderr, “%s: %s\n”, s, “error message”);