fgetc
头文件 | #include<stdio.h> |
原型 | int fgetc(FILE *stream); |
说明 | 从stream指向的输入流(若存在)中读取unsigned char型的下一个字符的值,并将它转换为int型。然后,若定义了流的文件位置指示符,则将其向前移动。 |
返回值 | 返回stream所指输入流中的下一个字符。若在流中检查到文件末尾,则设置该流的文件结束指示符并返回EOF。如果发生读取错误,就设置该流的错误指示符并返回EOF。 |
实例代码:
#include<stdio.h> int main() { FILE* pf = fopen("test.txt", "r"); if (pf == NULL) { return 1; } //读文件 int ch = 0; while ((ch = fgetc(pf)) != EOF) { printf("%c ", ch); } fclose(pf); pf = NULL; return 0; }
执行:(前提已经往里面写好了数据)
如何让fgetc在读取中途失败呢?
写法1:
首先把文件删掉
其次把代码改成:
#include<stdio.h> int main() { FILE* pf = fopen("test.txt", "r");//这个位置写成"r" if (pf == NULL) { return 1; } //读文件 int ch = 0; while ((ch = fgetc(pf)) != EOF) { printf("%c ", ch); } fclose(pf); pf = NULL; return 0; }
执行:
写法2:如果文件中字符不等于10个,就会读取失败(举例)
#include<stdio.h> #include <stdlib.h> int main() { FILE* fp; char str[20]; fp = fopen("test.txt", "r"); if (fp == NULL) { printf("打开文件失败\n"); exit(EXIT_FAILURE); } if (fread(str, sizeof(char), 9, fp) != 10) { printf("读取文件失败\n"); exit(EXIT_FAILURE); } fclose(fp); return 0; }
执行:
前提是我的文件写入26个字母
这里要读取的就是9个字符
8. 文件缓冲区💥
ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“ 文件缓冲区 ” 。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等),缓冲区的大小根据C编译系统决定的。
画图:写一个程序( 黄色那块区域, ),创建了很多变量、数组等等,它们都在内存( 蓝色的那块区域)里面。 橘黄色的那块就是我们的缓冲区:输出缓冲区和输入缓冲区。
当我们想把我们程序的数据写到硬盘上(也就是文件里面去的时候),不是直接就写到硬盘里面去,而是先写到输出缓冲区里面去,当缓冲区放满了或者说主动把数据放到硬盘里面,它自动再把输出缓冲区的数据放到硬盘里面去。
而输入的时候,从硬盘里读数据放到输入缓冲区,然后再把输入缓冲区的数据放到程序数据区里面去。
其实这就是一个提高效率的问题:就以fwrite为例吧,操作系统可以从电脑里面写数据与读数据,提供了一堆的API(接口),c语言凭什么可以操作文件呢?其实因为操作系统有一些接口可以操作文件。而fwrite是c语言的一个函数,通过利用fwrite函数写的一个代码称为用户程序,用户程序调用操作系统提供的一些接口然后去操作文件的。
所以说调用这些函数写文件或者读文件的时候严格来说会频繁打断操作系统,所以说能不能写上一堆然后一次搞定呢?所以就提供了输入和输出缓冲区。一个同学一次问10个问题和频繁地分时间问问题的效果是一样的,只是效率问题,这个资源就可以腾出来给其他同学服务。
实例代码理解缓冲区问题:
//VS2013 WIN10环境测试 //#include<stdio.h> //#include<stdlib.h> //#include<Windows.h> int main() { FILE* pf = fopen("test.txt", "w"); fputs("abcdef", pf);//先将代码放在输出缓冲区 printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n"); Sleep(10000); printf("刷新缓冲区\n"); fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘) //注:fflush 在高版本的VS上不能使用了 printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n"); Sleep(10000); fclose(pf); //注:fclose在关闭文件的时候,也会刷新缓冲区 pf = NULL; return 0; }
睡眠sleep就是,程序在这停止了,不继续往下执行,停了10秒后,再继续执行,这样有助于我们
观察数据从缓冲区到文件的过程。
不写fflush刷新会写入到文件里面吗?
可以理解为提前写入了。因为本来他计划的是程序执行结束之后再将缓冲区中的数据写入,现在是程序结束之前将数据写入文件。
9.实现一个代码,拷贝一个文件打开文件,打开被读的文件
int main() { //实现一个代码,拷贝一个文件 //打开文件 //打开被读的文件 FILE* pfRead = fopen("test1.txt", "r"); if (pfRead == NULL) { perror("open file for read"); return 1; } //打开要写的文件 FILE* pfWrite = fopen("test2.txt", "w"); if (pfWrite == NULL) { fclose(pfRead); pfRead = NULL; pfRead = NULL; perror("open file for write"); return 1; } //拷贝 int ch = 0; while ((ch=fgetc(pfRead)) != EOF) { fputc(ch,pfWrite); } //关闭文件 fclose(pfRead); pfRead = NULL; fclose(pfWrite); pfWrite = NULL; return 0; }
执行:
test1:起始文件
test2:目标文件
c语言的文件操作到这里就写完了,如有不对的地方,欢迎大佬的指导,感谢您的来访!