一、文件的打开和关闭
如果需要对文件进行一些读写操作,那么首先就需要先打开文件,在使用完以后关闭文件,所以最基本是打开文件和关闭文件。
ANSIC规定使用fopen函数来打开文件,fclose来关闭文件
打开文件 FILE *fopen(const char *filename,const char *mode); 关闭文件 FILE *fclose(FILE *stream);
二、文件的打开模式
mode表示文件的打开模式,下面都是文件的打开模式 :
⽂件使⽤⽅式 | 含义 | 如果指定⽂件不存在 | |||
“r”(只读) | 为了输⼊数据,打开⼀个已经存在的⽂本⽂件 | 出错 | |||
“w”(只写) | 为了输出数据,打开⼀个⽂本⽂件 | 建⽴⼀个新的⽂件 | |||
“a”(追加) | 向⽂本⽂件尾添加数据 | 建⽴⼀个新的⽂件 | |||
“rb”(只读) | 为了输⼊数据,打开⼀个⼆进制⽂件 | 出错 | |||
“wb”(只写) | 为了输出数据,打开⼀个⼆进制⽂件 | 建⽴⼀个新的⽂件 | |||
“ab”(追加) | 向⼀个⼆进制⽂件尾添加数据 | 建⽴⼀个新的⽂件 | |||
“r+”(读写) | 为了读和写,打开⼀个⽂本⽂件 | 出错 | |||
“w+”(读写) | 为了读和写,建议⼀个新的⽂件 | 建⽴⼀个新的⽂件 | |||
“a+”(读写) | 打开⼀个⽂件,在⽂件尾进⾏读写 | 建⽴⼀个新的⽂件 | |||
“rb+”(读写) | 为了读和写打开⼀个⼆进制⽂件 | 出错 | |||
“wb+”(读写) | 为了读和写,新建⼀个新的⼆进制⽂件 | 建⽴⼀个新的⽂件 | |||
“ab+”(读写) | 打开⼀个⼆进制⽂件,在⽂件尾进⾏读和写 | 建⽴⼀个新的⽂件 |
三、文件路径
在打开和关闭文件一般直接输入指定的文件名,当然也可以根据文件的路径对该文件进行操作。
路径分为:
- 绝对路径
- 相对路径
- . 表示当前路径
- … 上一级路径
对此当前文件test1.txt在D:\code\2024\2024\Document(绝对路径) FILE* pf = fopen("C:\\Users\\zpeng\\Desktop\\test.txt", "w"); 当test1.txt在其他文件夹中,可以通过上面表示的关系寻找 FILE* pf = fopen(".\\..\\..\\hehe\\test.txt", "w");
四、文件打开和关闭函数
4.1 fopen()
FILE *fopen(const char * filename, const char * mode)
【说明】:
- 功能:打开其名称在参数 filename 中指定的文件,并将其与流相关联,该流可在将来的操作中通过返回的
FILE指针
进行标识。 - 返回值:如果文件成功打开,该函数将返回指FILE对象的指针,该对象可用于在将来的操作中标识流,如果文件没有成功打开,则将返回NULL。
- 允许对流执行的操作以及如何执行这些操作由 mode 参数定义
4.2 fclose()
int fclose(FLIE *stream)
【说明】:
- 功能:关闭与流关联的文件并取消关联
- 与流关联的所有内部缓冲区都将与其解除关联并刷新:写入任何未写入的输出缓冲区的内容,并丢弃任何未写入输入缓冲区的内容。(更新缓冲区)
- 返回值:流关闭成功,则返回0。关闭失败,返回EOF
五、顺序读写函数
这里所有的输入流、输出流分别指stdin(标准输入流)、stdout(标准输出流)和文件流
5.1 fputc()
【函数部分说明】:
功能上:
将字符写入流并推进位置指示器,然后自动前进1。适用于所有输入流(字符输入到流中)
参数部分上:
character:
- 将要写入的字符的整型提升
- 写入时,该值在内部转换为无符号字符
stream:
- 指向标识输出流的FILE对象指针
返回值:
- 成功,将返回写入的字符。发生写入错误,则返回EOF并设置错误指示符(ferror)
int main() { FILE* pf = fopen("test1.txt", "w"); if (pf == NULL) { perror("fopen fail!!!"); return; } fputc('d', pf); fputc('e', pf); fclose(pf); pf = NULL; return 0; }
【使用说明】:
- 首次调用fputc函数将字符‘d’写入到文件当中,位置指示器向前+1就会指向‘d’的下一个位置,第二次fputc函数时,字符‘e’在这个位置输入进去。
- 注意这里对流执行写操作"w"模式
- 对于stream可以是文件流也可以是标准流
【练习】:使用fputc将A ~Z个字符输入到指定文件和显示器中
int main() { FILE* pf = fopen("test1.txt", "w"); if (pf == NULL) { perror("fopen fail!!!"); return; } for (char i = 'A'; i <= 'Z'; i++) { fputc(i, pf);//输入到文件中 fputc(i, stdout);//输入到显示器中 } fclose(pf); pf = NULL; return 0; }
5.2 fgetc()
【函数部分说明】:
- 功能:字符输入函数,从流中获得字符,返回指定流的内部文件位置指示符当前指向的字符,内部文件位置指示器将前进到下一个字符
- 返回值:成功后,将返回字符读取(进行整型提升)。如果失败则,返回EOF
int main() { FILE* pf = fopen("test1.txt", "r"); if (pf == NULL) { perror("fopen fail!!!"); return; } char ch; //ch用于接收fgetc从流中获得的字符 ch = fgetc(pf); printf("%c", ch); ch = fgetc(pf); printf("%c", ch); fclose(pf); pf = NULL; return 0; }
【使用说明】:
- 这里对流的操作采用mode是"r"模式
- 此时在指定文件提前写入数据,使用fgetc读取该文中的数据,第一次使用时读取‘h’字符,指示器++1,指向‘e’字符位置,在第二次使用读取该字符。
- 当然也可以直接从键盘读取数据(使用标准输入流stdin)–>改为
ch = fgetc(stdin);
5.3 实现文件拷贝
通过以上两个函数,我们可以用来实现文件拷贝的场景
int main() { FILE* pfread = fopen("data1.txt", "r"); if (pfread == NULL) { perror("fopen fail!!!"); return; } FILE* pfwrite = fopen("data2.txt", "w"); if (pfwrite == NULL) { fclose(pfread);//读文件操作没有必要 pfread=NULL; perror("fopen fail!!!"); return; } char ch; while ((ch = fgetc(pfread)) != EOF) { fputc(ch, pfwrite); } fclose(pfread); fclose(pfwrite); return 0; }
【使用说明】:
- 这里先提前准备好两个文件,并且在
data1.txt
中提前输入数据 - 这里需要对两个不同文件使用不同mode打开,对
data1.txt
使用读的形式,而data2.txt
是写的形式打开 - 在while循环中一个从
data1.txt
读取字符,同时一个向data2.txt
输入字符,直到读取完成或者发生错误
5.4 fputs()
【函数部分说明】:
- 功能:文本行输入函数,将str指向的字符串写入流中,从指定的地址开始复制,直到结束标志\0(\0’字符不会复制到流中)
- 返回值:成功,返回一个非负值,失败,则返回EOF
int main() { FILE * pf = fopen("test1.txt", "w"); if (pf == NULL) { perror("fopen fail!!!"); return; } //fputs("hellow world", pf); -- 将字符串输入到文件流中 fputs("hellow world", stdout); -- 将字符串输入到输出流中(打印到屏幕上) fclose(pf); pf=NULL; return 0; }
【C语言】探索文件读写函数的全貌(二)https://developer.aliyun.com/article/1617244