在程序设计中,一般谈论的文件有两种:程序文件,数据文件。
包括源程序.c文件,目标文件. obj,可执行程序.exe文件。
本文讨论文件类型是数据文件。
文件的内容不一定是程序,而是程序运行时读写的数据。
一个文件要有一个唯一的文件标识,如我们的身份证号一样用于识别。
文件名包含三部分:文件路径+文件名主干+文件后缀
如:c:\code\test.txt
每个被使用的文件都会在内存中开辟一个相应的文件信息区(如文件名,文件状态以及文件当前位置等)。这些信息保存在一个结构体变量中,该结构体是系统声明的,取名FILE
struct iobuf {
char* _ptr;
char* _base;
int _flag;
};
typedef struct iobuf FILE;
每个被使用的文件都自动开辟了FILE类型的结构体变量。
我们一般通过一个FILE的指针对其进行维护。
下面我们创建一个FILE*的指针变量
FILE *pf;//文件指针变量
文件在读写时应先打开,使用完毕后应关闭。
ANSIC规定使用fopen函数打开文件,用fclose函数关闭。
//打开文件
FILE * fopen ( const char * filename, const char * mode );
//关闭文件
int fclose ( FILE * stream );
//代码演示
#include
int main() {
FILE* pf;
//打开文件
pf = fopen("text.txt", "w");
//文件操作
if (pf != NULL)
{
fputs("fopen example", pf);
//关闭文件
fclose(pf);
}
return 0;
}
int main()
{
//打开文件
FILE* pf = fopen("test.txt", "w");
//检验是否打开文件成功
if (NULL == pf)
{
perror("fopen");
return 1;
}
//写文件
int i = 0;
for (i = 0; i < 26; i++)
{
fputc('a'+i, pf);
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
文件随机读写就是根据文件指针的位置和偏移量来定位文件
`int fseek ( FILE * stream, long int offset, int origin );
//test.txt文档内容为26个英文字母
int main() {
FILE* ps = fopen("test.txt", "r");
if (ps == NULL)
{
perror("fopen():");
}
int ch = fgetc(ps);
printf("%c", ch);//结果 a
fseek(ps, 2,SEEK_SET);
ch = fgetc(ps);
printf("%c", ch);// c
fseek(ps, 2, SEEK_CUR);
ch = fgetc(ps);
printf("%c", ch);// f
fseek(ps, -1, SEEK_END);
ch = fgetc(ps);
printf("%c", ch);// z
fclose(ps);
ps = NULL;
return 0;
}
返回文件指针相对于起始位置的偏移量
long int ftell ( FILE * stream );
int main() {
FILE* ps = fopen("test.txt", "r");
if (ps == NULL)
{
perror("fopen():");
}
int ch = fgetc(ps);
printf("%c ", ch);
int pos=ftell(ps);
printf("%d\n", pos);
fseek(ps, 2,SEEK_SET);
ch = fgetc(ps);
printf("%c ", ch);
pos = ftell(ps);
printf("%d\n", pos);
fseek(ps, 2, SEEK_CUR);
ch = fgetc(ps);
printf("%c ", ch);
pos = ftell(ps);
printf("%d\n", pos);
fseek(ps, -1, SEEK_END);
ch = fgetc(ps);
printf("%c ", ch);
pos = ftell(ps);
printf("%d\n", pos);
fclose(ps);
ps = NULL;
return 0;
}
让文件指针的位置回到文件的起始位置
void rewind ( FILE * stream )
int main() {
FILE* ps = fopen("test.txt", "r");
if (ps == NULL)
{
perror("fopen():");
}
int ch = fgetc(ps);
printf("%c ", ch);
int pos = ftell(ps);
printf("%d\n", pos);
rewind(ps);
pos = ftell(ps);
printf("%d\n", pos);
fclose(ps);
ps = NULL;
return 0;
}
牢记:在文件读取的过程中,不能用feof函数的返回值判断文件是否结束。
而是应用与当文件读取结束时,判断是读取失败结束,还是遇到文件尾结束。
1.文本文件读取是否结束,判断返回值是否为EOF(fgetc()函数),或者为NULL(fgets()函数)
列如:
fgetc()判断是否为EOF;
fgets()的返回值是否为NULL;
2.二进制文件的判断读取结束,判断返回值是否小于要读取的个数
fread()函数判断返回值是否小于实际要求读取的个数
文本文件的例子
#include
#include
int main(void)
{
int c; // 注意:int,非char,要求处理EOF
FILE* fp = fopen("test.txt", "r");
if(!fp) {
perror("File opening failed");
return EXIT_FAILURE;
}
//fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
while ((c = fgetc(fp)) != EOF) // 标准C I/O读取文件循环
{
putchar(c);
}
//判断是什么原因结束的
if (ferror(fp))
puts("I/O error when reading");
else if (feof(fp))
puts("End of file reached successfully");
fclose(fp)
}