由于博主本身技术水平限制,文章中的问题漏洞还请批评指出
下面是几个常用的文件IO函数。都在<stdio.h>中。
基本函数:
(1)FILE * fopen(const char * path,const char * mode);
功能:用指定模式打开指定文件文件。
参数1:待打开文件的路径。注意反斜杠的转义问题。
参数2:指定打开文件的模式。字符串是组合起来的。
第一个字符应该是’a’,‘w’,‘r’之中的一个。分别表示追加(在最后附加上去),写入(清空后从头写),读取。若没有该文件,‘a’或’w’会自动新建文件;‘r’不会,只是返回NULL。
后面的一个是’t’和’b’之中的一个,其中’t’可以省略不写。分别表示文本模式和二进制模式。
再后面可以加上’+’,也可以不加。加上表示既可以读,也可以写。
返回值:文件成功打开后,返回对应的的文件指针;如果失败(如没找到文件),返回NULL。所以可以用这个比较简单的办法检测是否存在某个文件。
(2)int fclose(FILE *fp );
功能:关闭一个流,释放文件指针和有关的缓冲区。
返回值:如果流成功关闭,返回 0,否则返回EOF。
实测如果没有加上,影响不大。但是还是加上为妙。这与fopen函数是一对,与malloc函数和free函数成对是一个道理。
(3)int feof (FILE *stream)
功能:如果到达文件末尾,则返回非0值,否则返回0。
注意:feof函数判断文件结束是通过读取函数fread/fscanf等返回错误来识别的,故而判断文件是否结束应该是在读取函数之后进行判断。
具体研究一下feof函数的返回值情况。如Feof.c所示,运行结果如图1。
//Feof.c
//研究feof函数的返回值情况
#include <stdio.h>
char str[]="abc.txt";//文件内容如图1.3所示
int main()
{
FILE *fp=fopen(str,"r");
int i;
for(i=0;i<5;i++)
{
printf("feof:%02X\n",feof(fp));
printf("getc:%02X\n",(unsigned char)getc(fp));
}
fclose(fp);
return 0;
}
图1 Feof.c运行结果
经过分析,对于feof函数的返回值,可以得出下表规律:
状态 | 读取之前的返回值 | 读取之后的返回值 |
---|---|---|
正常读取 | 0 | 0 |
到达末尾 | 0 | 非0 |
也就是说,在读取函数调用时发现已经到达末尾,设置一个指示器。然后feof函数只是返回指示器是否被设置。所以要在调用读取函数之后才能正确返回状态。
(4)int fseek(FILE *stream, long offset, int fromwhere);
功能:设置文件指针stream的光标位置。
参数2:offset是偏移量(单位为字节)。(注意,类型是long,所以在操作大文件时要格外注意,也可以参考一下lseek函数,在这里就不展开介绍了)
参数3:是偏移量的基准。有三个宏可以直接使用:
文件头(SEEK_SET);当前位置(SEEK_CUR);文件尾(SEEK_END)。
下面具体举例进行解释:
FILE *fp;
fseek(fp,5L,SEEK_SET);
//从头往后偏移5个字节
//即下一次读取第6个字节
fseek(fp,-2L,SEEK_CUR);
//从现在位置向前偏移2个字节
//设现在读取会是第n个字节
//则调用完函数后读取会是第(n-2)个字节
fseek(fp,-3L,SEEK_END);
//从文件末尾向前偏移3个字节
//设文件总长为n个字节
//则调用完函数后读取第(n+1-2)个字节
这个函数在实际使用中还是比较有用的。
(5)long ftell(FILE *stream);
和fseek函数相对,这个函数返回当前离文件开头有几个字节。
设现在读取会是第n个字节,则返回(n-1)。这两个函数要注意植树问题。
这两个函数结合起来可以方便地知道文件大小:
fseek(fp, 0,SEEK_END);
len=ftell(fp);
首先将文件的当前位置移到文件的末尾,然后调用ftell函数获得当前位置,则返回值等于文件所含字节数。
(6)void rewind(FILE *stream);
等价于fseek(stream,0,SEEK_SET);
读取函数及实现代码:
(1)int getc(FILE *stream);
(2)int fgetc(FILE *stream);
我并不觉得这两个函数有什么区别,因此放在了一起。
功能:在stream中读取一个字符,并返回。
返回值:若正常读取,返回字符;若出现异常(包括读到文件最后),返回EOF。
文本模式
在文本模式下,可以直接用判断getc函数的返回值是否为EOF来判断是否结束。如GetcTxt_A.c所示。
//GetcTxt_A.c
//getc函数文本模式遍历文件#A
#include <stdio.h>
char str[]="abc.txt";//读入文件
int main()
{
FILE *fp=fopen(str,"r");//以文本模式打开文件
unsigned char c=getc(fp);//一定要先读取一个再判断
while(c!=(unsigned char)EOF)
{
//不直接输出字符是因为有些字符无法察觉
//但是用输出十六进制可以保证发现全部的输出
printf("%02X ",c);