1.fopen()函数
这一函数在stdio.h中声明,它的第一个参数是要打开的文件名,更确切的说,是包含该文件名的字符串的地址。第二个参数是用于指定文件打开模式的一个字符串。C库提供了一些可能的模式如下:
模式字符串 | 意义 |
“r” | 打开一个文本文件,可以读取文件 |
“w” | 打开一个文本文件,可以写入文件,先将文件的长度截为0,如果文件不存在则创建之 |
“a” | 打开一个文本文件可以写入文件,向已有文件的尾部追加内容,如果该文件不存在则创建之 |
“r+” | 打开一个文本文件,可以进行更新,也即可以读取和写入文件 |
“w+” | 打开一个文本文件,可以进行更新(读取和写入),如果该文件存在则首先长度截为0,若不存在则创建之 |
“a+” | 打开一个文本文件,可以进行更新(读取和写入),向已有文件的尾部追加内容,如果文件不存在则创建之,可以读取整个文件,但写入时只能追加内容 |
“rb”,”wb”,”ab” “ab+”,”a+b”,”wb+” “w+b”,”ab+”,”a+b” | 与前面的模式相似,只是使用二进制模式而非文本模式打开文件 |
Eg :FILE *fp;
char *filepath;
fp = fopen(filepath,”r”);
注意:如果使用任何一种w模式打开一个已有的文件,文件的内容将被删除,以便程序一个空文件开始操作。
程序成功打开一个文件后,fopen函数返回一个文件指针,其他io函数用这个指针来指定该文件。文件指针(fp)是一种指向FILE的指针。FILE定义在stdio.h中,指针fp并不指向实际的文件,而是指向一个关于文件的信息的数据包。
typedef struct _iobuf
{
char* _ptr;//文件输入的下一个位置
int _cnt;//当前缓冲区的相对位置
char* _base;//基址,即文件的起始位置
int _flag;//文件标志
int _file;//文件的有效性验证
int _charbuf;//检查缓冲区的状况,如果无缓冲区则不读取
int _bufsiz;//文件的大小
char* _tmpfname;//临时文件名
} FILE;
如果不能打开文件,fopen返回的是一个空指针
ch = getc(fp)//从fp指针指定的文件中获得一个字符
putc(ch,fpout)//把ch写入FILE指针fpout指定的文件中。
如果在尝试读入字符时发现已经到达文件结尾,getc函数会返回一个特殊值EOF,所以C语言只有在读取超出文件结尾以后才会发现文件的结尾,为了避免试图读取空文件带来的问题,应该对文件的输入使用入口条件循环(而非do while循环)。鉴于getc函数的设计,程序应该在进入循环体之前尝试进行第一次读取。所以下面是一个比较好的模式:
char ch;
while((ch = getc(fp)) != EOF) {…}
函数
fclose(fp)函数关闭由指针fp指定的文件,同时根据需要刷新缓冲区。更正规的程序也行还要检查是否成功关闭了文件,如果成功关闭,返回0,否则返回EOF。(磁盘已满,磁盘被移走或者出现io错误等都会导致fclose执行失败)。
fscanf 和fprintf函数与scanf和printf的工作方式类似。
FILE *fp;
fp = fopen(filename,’a+’);
fprintf(fp,”%s”,word);//向fp指向的文件写入word指向的字符串
fscanf(fp,”%s”,word);//从fp指向的文件读取字符串到word中
rewind(fp)//回到文件的开始处。
和ftell().
fseek的3个参数中,第一个参数是指向被搜索文件的FILE指针,应该已经使用fopen打开了该文件
第二个参数称为偏移量,表示从起点开始要移动的距离,这个参数必须是一个long类型的值,可以为正(前移)负(后移),一可以为零。
第三个参数是模式,用来标识起点。在ANSI下,stdio.h头文件指定了下列模式常量:
SEEK_SET:文件的开始
SEEK_CUR:当前位置
SEEK_END:文件的结尾
eg:
fseek(fp,0L,SEEK_SET)//找到文件的开始处,等价与rewind(fp)
fseek(fp,10L,SEEK_SET)//找到文件的第10个字节
fseek(fp,2L,SEEK_CUR)//从当前位置向前移动2个字节
fseek(fp,-10L,SEEK_END)//从文件结尾处退回10个字节
如果一切正常,fseek返回值为0,如果有错误出现,例如试图移动超出文件范围,fseek返回值为-1.
ftell为long类型,它返回当前文件的位置。ftell函数通过返回距离文件开始处字节数目来确定文件的位置。文件的第一个字节到文件开始处的距离是字节0,依次类推。在ANSI C下,这种定义适用于以二进制模式打开的文件,但是对于以文本模式打开的文件来讲,不一定是这样。
二进制IO:fread() 和fwrite()
fwrite的原型是:
size_t fwrite(const void *restrict ptr, size_t size, size_t nmemb, FILE * restrict fp);
fwrite()函数将二进制数据写入文件,指针ptr是要写入的数据块的地址,size表示要写入的数据块的大小,以字节为单位,nmemb表示数据块的数目,fp指定要写入的文件。例如要保存一个256字节大小的数据对象(比如数组)可以这样写:
char buffer[256];
fwrite(buffer,256,1,fp);
这一调用将一块256字节的数据块从缓冲区写入了文件。又比如要保存一个包含10个double值的数组可以这样做:
double earnings[10];
fwrite(earnings,sizeoof(double),10,fp);
fwirte会返回成功写入的项目数,正常情况下他与nmemb相等,如果有写入错误的话,返回值就会小于nmemb。
fread()的原型为
size_t fread(void *restrict ptr, size_t size, size_t nmemb, FILE *restrict fp);
fread()与fwrite()函数的参数相同,ptr为读入文件数据的内存存储地址,fp指定要读取的文件,使用这一函数来读取通过fwrite函数写入的数据,例如要恢复前一例子中保存的10个double值的数组可以如下调用:
double earnings[10];
fread(earnings,sizeof(double),10,fp);
fread会返回成功读取的项目数,正常情况下他与nmemb相等,如果有读取错误的话,返回值就会小于nmemb。
当标准输入函数返回EOF时通常表示已经达到了文件结尾,可是这也有可能表示发生了读取错误,使用feof()和ferror()可以区分这两种情况,如果最近一次输入输出调用检测到文件的结尾,feof返回一个非零值,否则返回零。如果发生读写错误,ferror返回一个非零值,否则返回一个零。