1.程序文件、数据文件
程序文件:源程序文件(.c),目标文件(.obj),可执行程序(.exe)
数据文件:文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。我们讨论的是数据文件。
我们把信息输出到磁盘上,当需要的时候再从磁盘上读取,这里处理磁盘上文件。
2.文件名:文件路径+文件名主干+文件后缀
c:\code\test.txt(test文件名主干)
3.文件两种类型:文本文件(肉眼可看懂)二进制文件(看不懂的)
数据在内存中以二进制形式存储,如果不加转换直接输出到外存(直接放在文件里)就是二进制文件。如果要求在外存上以ASCII码的形式存储,则需要在存储前转换,以ASCII码字符的形式存储的文件就是文本文件。
字符一律以ASCII存储,数值可以ASCII,可以二进制;如整数10000,ASCII码形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制则在磁盘上只占4个字节。
4.文件指针:每个被使用的文件都在内存中开辟了一个相应的文件信息区用来存放文件的相关信息(如文件名,文件状态以及文件当前的位置),这些信息都是保存在一个结构体变量里的,该结构体类型是有系统说明的,取名FILE。 一般用过一个FILE的指针维护这个结构体变量。
5.文件的打开和关闭:文件读写之前打开文件,使用结束之后关闭文件
在打开文件的同时都会返回一个FILE*的指针变量指向该文件
FILE*pf=fopen("test.txt,"r");//以只读的形式打开,如果打开失败不会创建一个文件
//如果以w形式打开,如果指定文件不存在,会建立一个新文件//如果指定文件存在,原来的文件内容会消失
//有一个pf的指针,如果打印成功,则指向这个FILE类型的结构体变量,如果打开失败,则pf是一个空指针。
if(pf==NULL){
printf("%s\n",strerror(errno));//报错原因
return 0;
}
//打开成功//
//读文件
//关闭文件
fclose(pf);//让这个结构体的资源释放掉,但pf不是空指针
pf=NULL;//把pf变成空指针
return 0;
}
6.文件的顺序读写
ps:文件名不区分大小写
int main(){
FILE*pfRead=fopen("TEST.txt","r");
FILE*pfWrite=fopen("testone.txt","w");
if(pfRead==NULL){
printf("Error opening file:%s\n",strerror(errno));
return 0;
}
if(pfWrite==NULL){
printf("Error opening file:%s\n",strerror(errno));
return 0;
}
int ch;
while((ch=fgetc(pfRead))!=EOF){
fputc(ch,pfWrite);
}
fclose(pfRead);
fclose(pfWrite);
pfWrite=NULL;
pfRead=NULL;
return 0;
}
7.系统默认打开stdin(键盘),stdout(屏幕),stderr,三个都是FILE*
int main(){
int ch=fgetc(stdin);
fputc(ch,stdout);
return 0;
}
8.
#include <stdio.h>
int main() {
char buf[1024] = {0};
FILE* pf = fopen("test.txt", "r");
if(pf == NULL) {
return 0;
}
fgets(buf, 1024, pf); //文件指针移动到第一行末尾
printf("%s", buf);
fgets(buf, 1024, pf); //文件指针从第一行开头开始
printf("%s\n",buf);
fclose(pf);
return 0;
}
9.
struct S{
int n;
float score;
char arr[10];
};
int main(){
struct S s={0};
FILE*pf=fopen("test.txt","w");
if(pf==NULL){
return 0;
}
// //格式化的形式写文件
// fprintf(pf,"%d %f %s",s.n,s.score,s.arr); //把各种格式的数据都写进了文件
//格式化的形式输入数据(文件里的数据放入s)
fscanf(pf,"%d %f %s",&s.n,&s.score,s.arr);//键盘用stdin
printf("%d %f %s",s.n,s.score,s.arr);//stdout
fclose(pf);
pf=NULL;
}
10.自己拓展一下C语言MYSQL数据库
struct S{
char name[20];
int age;
double score;
};
int main(){
struct S s={"zhangsan",20,55.6};
FILE*pf=fopen("text.txt","wb");
if(pf==NULL){
return 0;
}
//二进制形式写文件//将数据块写入文件
fwrite(&s,sizeof(struct S),1,pf);//指向结构体的指针;结构体的字节数;结构体的数量;指向文件的指针
//fread(&tmp,sizeof(struct S),1,pf);//二进制的形式读文件,放进结构体tmp
fclose(pf);
pf=NULL;
return 0;
}
11.前面讲的都是文件顺序读写,以下是文件的随机读取:
打开文件时文件指针默认在文件开始
int main(){
FILE*pf=fopen("text.txt","r");
if(pf==NULL){
return 0;
}
//fseek()移动一个文件指针到一个特定的位置,参数:文件指针;偏移量(几字节)(整数向后偏移,负数向前偏移);文件指针的当前位置(把文件指针从当前位置移动偏移量)
//文件指针的当前位置可以写三种 SEEK_CUR(文件指针的当前位置)SEEK_END(文件末尾位置) SEEK_SET(文件起始位置)
fseek(pf,2,SEEK_CUR);
int ch;
ch=fgetc(pf);
printf("%c\n",ch);
fclose(pf);
pf=NULL;
return 0;
}
文件内容如果是a b c d e f 文件结尾是f后面,偏移量为-2才会打印e,上面代码里说的文件指针只是文件里的一个指针,不是文件指针,文件指针指向这个文件,不能改变他的位置,不然找不到文件在哪了
fseek
函数用于设置文件位置指针的位置。它的原型如下:
int fseek(FILE *stream, long int offset, int whence);
这里是三个参数的含义:
stream
:指向FILE
对象的指针,它指定了要设置位置指针的文件。offset
:偏移量,指定了相对于whence
参数指定的位置的偏移量。whence
:指定了偏移量的基准位置,可以是SEEK_SET
(文件开头)、SEEK_CUR
(当前位置)或者SEEK_END
(文件末尾)。
fseek
函数的作用是将文件位置指针移动到指定位置。例如,fseek(pf, 3, SEEK_SET)
将文件位置指针移动到文件的第三个字节处。
12.rewind():让文件位置指针回到文件起始位置
13.文件结束判定:在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否结束,而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾部结束
文本文件读取结束判断:判断返回值是否为EOF(fgetc),或者NULL(fgets)
例如:fgetc判断是否为EOF,fgets判断返回值是否为NULL(EOF/NULL--文件已经读取结束,再用feof来判断它是为什么结束)
二进制文件的读取结束判断:判断返回值是否小于实际要读的个数
例如:fread判断返回值是否小于实际要读的个数(fread函数会返回实际读取到的count数目,如果此值比参数count来得小,则代表可能读到了文件尾部或者有错误发生,这是必须用feof函数或ferror来决定发生了什么情况,返回值返回实际读取到的count数量)
14
int main(){
FILE*pf=fopen("test2.txt","r");
if(pf==NULL){
perror("hehe");
return 0;
}
fclose(pf);
pf=NULL;
return 0;
} //运行结果 hehe: No such file or directory(括号里的东西冒号空格报错原因)
int main(){
int c;
FILE*fp=fopen("test.txt","r");
if(!fp){
perror("File opening failed");
return EXIT_FAILURE;
}
while((c=fgetc(fp))!=EOF){
putchar(c);//读一个字符打印一个字符直到EOF (错误或文件结束)
}
if(ferror(fp)){//发生错误返回非0,没有错误返回0
puts("I/O error when reading");
}else if(feof(fp)){//文件结束返回非0,否则返回0
puts("End of file reached successfully");
}
fclose(fp);
return 0;
}