Day 12
文件操作
-
- 文件
- 文件操作
- 文件函数
- 课堂笔记
文件
1)概述
FILE 所有平台的名字都一样,FILE 是一个结构体类型,里面的成员功能一样,不同平台成员的名字不一样。
FILE *fp
1、fp指针,只用调用了fopen().在堆区分配空间,把地址返回给fp
2、fp指针不是指向文件,fp指针和文件关联,fp内部成员保存了文件的状态
3、操作fp指针,不能直接操作,必须通过文件库函数来操作fp指针
4、通过库函数操作fp指针,对文件的任何操作,fp里面成员会相应的变化(系统自动完成)
2)文件分类
(1)磁盘文件
指一组相关数据的有序集合,通常存储在外部介质(如磁盘)上,使用时才调入内存。
(2)设备文件
在操作系狁一个与主机相连的输入、输出设备看作是一个文件,把它们的输入、输出等同于对磁盘文件的读和写
(3)从用户或者操作系统使用的角度(逻辑上)把文件分为:
1)文本文件:基于字符编码的文件
2)二进制文件:基于值编码的文件
3)文件操作流程
1、打开文件fopen()
2、读写文件
1)按字符读写fgetc(),fputc()
2)按字符串(行)读取文件fgets(),fputs()
3)文件结尾判断 feof()
3、关闭文件fclose()
文件操作
标准文件设备指针
#include<stdio.h>
int main()
{printf("aaaaaaa\n");//fclose(stdout); //关闭标输入文件指针printf("bbbbbbbbbbbbb\n");//打印库文件函数调用失败的原因perror("mike");fclose(stderr);perror("jiang");int a = 10;printf("请输入a:");fclose(stdin);scanf("%d",&a);printf("a = %d\n",a);return 0;
}
标准设备补充
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{//printf函数的内部实现,往标准输出设备(1)写内容printf("before aaaaaaa\n");//fclose(stdout);close(1); //1代表就是标准输出设备,关闭了,1就是空闲的数字int fd = open("01.txt", O_WRONLY,0777);//printf函数的内部实现,往(1)写内容,但是1现在和01.txt关联。printf的内容写到01.txtprintf("fd = %d\n",fd);printf("after bbbbbbb\n"); printf("after ddddddd\n");printf("after ccccccccc\n");return 0;
}
文件的打开和关闭
#include<stdio.h>
int main()
{FILE *fp = NULL;//打开成功,返回有效地址//打开失败,返回NULL//"w",如果文件不存在,新建,如果文件存在,清空内容再打开//"r",如果文件不存在,打开失败//"a"如果文件不存在,新建,如果文件存在,光标自动放在文件末尾fp = fopen("./02.txt","w");if(fp == NULL){perror("fopen");return 0;}fclose(fp);fp = NULL;return 0;
}
文件路径说明
1、在Linux,相对路径相对于可执行程序2、VS
a.编译同时运行程序,相对路径,相对于xxxx.vcxproj(项目文件)所在的路径
b.如果直接运行程序,相对路径相对于可执行程序3、Qt
a.a.编译同时运行程序,相对路径,相对于debug所在的路径
b.如果直接运行程序,相对路径,相对于可执行程序fopen("1.txt,""w");char *p = "1.txt";
fopen(p,"w");char p[] = "1.txt";
fopen(p."w");char *mode = "w";
fopen("1.txt",mode);
文件函数
- fputc的使用
#include<stdio.h> int main() {//1、打开文件FILE *fp = NULL;fp = fopen("02.txt","w");if(fp == NULL){perror("fopen");return -1;}//2、写文件fputc().一次只能写一个字符char ch = 'a';while(ch <= 'z'){fputc(ch,fp);ch++;}char buf[] = "abcdef";int i = 0;int n = strlen(buf);for(i = 0;i < n;i++){fputc(buf[i],fp);}fputc(1,fp);fputc(2,fp);fputc(-1,fp);fputc(97,fp);//3、关闭文件fclose(fp);fp = NULL;return 0; }int main01() {//1、打开文件FILE *fp = NULL;fp = fopen("01.txt","w");if(fp == NULL){perror("fopen");return -1;}//2、写文件fputc().一次只能写一个字符fputc('a',fp);fputc('b',fp);fputc('c',fp);fputc('d',fp);fputc('a',stdout);fputc('b',stdout);fputc('c',stdout);fputc('d',stdout);//3、关闭文件fclose(fp);fp = NULL;return 0; }
- fgetc的使用
#include<stdio.h> #include<string.h> //1、如果是文本文件,可以通过-1(EOF)判断文件是否结尾 void write_file() {//1、打开文件FILE *fp = fopen("03.txt","w");if(fp == NULL){perror("write_file fopen");return;}//2、写文件char *p = "abcdef";int i = 0;int n = strlen(p);for(i = 0;i < n;i++){fputc(p[i],fp);}//3、关闭文件fclose(fp); } void read_file() {//1、打开文件,以读的方式打开FILE *fp = fopen("03.txt","r");if(fp == NULL){perror("read_file fopen");return;}//2、读文件,每次读一个字符char ch;ch = fgetc(fp);printf("ch = %c\n",ch);ch = fgetc(fp);printf("ch = %c\n",ch);ch = fgetc(fp);printf("ch = %c\n",ch);//3、关闭文件fclose(fp);} int main() {write_file();read_file();return 0; }
- fgetc的补充1使用
#include<stdio.h> #include<string.h> //1、如果是文本文件,可以通过-1(EOF)判断文件是否结尾 void write_file() {//1、打开文件FILE *fp = fopen("04.txt","w");if(fp == NULL){perror("write_file fopen");return;}//2、写文件char *p = "abcdef";int i = 0;int n = strlen(p);for(i = 0;i < n;i++){fputc(p[i],fp);}//3、关闭文件fclose(fp); } void read_file() {//1、打开文件,以读的方式打开FILE *fp = fopen("04.txt","r");if(fp == NULL){perror("read_file fopen");return;}//2、读文件,每次读一个字符char ch;while(1){ch = fgetc(fp);printf("ch = %c\n",ch);//if(ch == -1) //1if(ch == EOF){break;}}//3、关闭文件fclose(fp);} int main() {write_file();read_file();return 0; }
- fgetc的补充2使用
#include<stdio.h> #include<string.h> //1、如果是文本文件,可以通过-1(EOF)判断文件是否结尾 void write_file() {//1、打开文件FILE *fp = fopen("05.txt","w");if(fp == NULL){perror("write_file fopen");return;}//2、写文件fputc('a',fp);fputc('b',fp);fputc(-1,fp);fputc('d',fp);fputc(-1,fp);fputc('e',fp);//3、关闭文件fclose(fp); } void read_file() {//1、打开文件,以读的方式打开FILE *fp = fopen("05.txt","r");if(fp == NULL){perror("read_file fopen");return;}//2、读文件,每次读一个字符char ch;while(1){ch = fgetc(fp);printf("ch = %d\n",ch);if(feof(fp))//如果文件结尾,返回真{break;}}//3、关闭文件fclose(fp);} int main() {write_file();read_file();return 0; }
- feof的使用
#include<stdio.h> int main() {//1、打开文件FILE *fp = fopen("06.txt","r");//2、写文件while(1){printf("文件没有结尾\n");int ch = fgetc(fp); //读取,目的是为了判断是否结尾printf("ch = %d\n",ch);if(feof(fp)) //如果到文件结尾,跳出循环{break;}}//3、关闭文件fclose(fp);return 0; }
- cat命令的实现
#include<stdio.h> int main(int argc, char *argv[]) {//1、打开文件,文件路径,argv[1],读方式FILE *fp = fopen(argv[1],"r");//2、读取文件内容,将文件内容显示到屏幕上char ch;while(1){ch = fgetc(fp);if(feof(fp)) //如果文件结尾,退出循环{break;}printf("%c",ch);}//3、关闭文件fclose(fp);return 0; }
- vi命令的实现
#include<stdio.h> #include<string.h> //scanf()不能空格 //gets()不能有回车 int main(int argc, char *argv[]) {//以写方式打开文件,w,路径为argv[1]FILE *fp = fopen(argv[1],"w");//从键盘读取内容fgets(),放在字符数组//字符数组内容,一个一个字符往文件写char buf[1024];while(1){fgets(buf,sizeof(buf),stdin);//如果用户输入的内容为:wq,结束,保存文件if(strncmp(buf,":wq",3)==0){break;}int i = 0;/*while(buf[i] != '\0') //读取的内容没有到结束符,读取到的内容写入文件{fputc(buf[i],fp);i++;}*/int n = strlen(buf);for(i = 0;i < n;i++){fputc(buf[i],fp);}}//关闭文件fclose(fp);return 0; }
- fputs的使用
#include<stdio.h> int main() {//打开文件FILE *fp = fopen("09.txt","w");/*//写文件char *p1 = "hello\n";fputs(p1,fp);char *p2 = "sdaf\n";fputs(p2,fp);char *p3 = "mike\n";fputs(p3,fp);*///指针数组,它是数组,每个元素都是指针char *p[] = {"hello\n","abc\n","mike\n"};int i = 0;int n = sizeof(p)/sizeof(p[0]);for(i = 0;i < n;i++){fputs(p[i],fp);}return 0; } int main01() {char buf[] = "hello";//把buf的内容写到stdout所代表的文件,显示屏幕fputs(buf,stdout);char *p = "mike";fputs(p,stdout);return 0; }
- fgets的使用
#include<stdio.h> int main() {//打开文件FILE *fp = fopen("10.txt","r");//读文件char buf[100];//1、从fp所关联的文件读取内容,放到buf,一次最大读取为sizeof(buf)-1//2、遇到换行符,文件结尾,出错,结束本次读取while(1){fgets(buf,sizeof(buf),fp);printf("buf = %s",buf);if(feof(fp))//如果到文件结尾,跳出循环{break;}}//关闭文件fclose(fp);return 0; }
课堂笔记
1、如果是文本文件,可以通过-1(E0F)判断文件是否结尾
2、如果是二进制文件,不能以-1判断文件结尾
3、feof()判断文件是否结尾,任何文件都能判断feof(fp);//如果到文件结尾,返回真
1、如果第一次没有对文件进行读操作,直接调用此函数,永远返回假(文件没有到结尾)
2、此函数必须,先读,再调用feof()才有意义
3、调用此函数,光标不会自动往后移动
4、必须读取后,才能判断是否结束,判断的是读取的字符