主观题:文本文件读写
### **任务描述:** 本关任务:编写函数,该函数从已有的当前目录下的文件`in.txt`中读取并解析出其中的数值,并将结果写到当前目录下的文件`out.txt`中。 ### **相关知识:** **文件** 文件是存储在某种长期储存设备(磁盘、光盘等)上的一段数据流。C 语言中把文件看成一个有序的字节流,每个文件都以文件结束标志( `EOF `)结束。 下图是包含` n` 个字节的文件内容:  磁盘文件由操作系统中的文件系统统一管理,也只有文件系统才能直接操作文件。所以编写 C 程序来操作文件实际上是需要调用文件系统的接口函数来实现,我们学习文件的操作也就是学习一些 C 语言库中提供的函数。 **文件类型** C 语言在对文件进行操作时,将文件分为**文本文件**和**二进制文件**。 1. 文本文件:指可以用任何文字处理程序阅读和编辑的简单 ASCII 文件; 1. 二进制文件:指一般含有特殊的格式或计算机代码,如图形文件和可执行文件等。 **文件的操作** C 语言中对文件的操作一般分为三个步骤:**打开文件**、**读写文件**、**关闭文件**。 * 打开文件 打开文件后,操作系统为文件建立一个文件控制结构(文件控制块),并在内存中建立一个缓冲区,该缓冲区的数据对应文件的数据,之后的文件读写操作实际上是在缓冲区中进行。 * 读写文件 通过文件控制块实现文件的输入输出。 * 关闭文件 将文件缓冲区中的数据写回到磁盘文件中,并释放文件控制块。 **操作文件的函数** 用 FILE 结构操作文件是 C 语言提供的文件操作方式,只要包含头文件stdio.h就能使用文件操作的相关函数。下面就给大家介绍一些函数的使用。 **打开文件** `fopen `是`stdio.h`提供的文件打开函数。 如下面的程序可以打开一个文件用于读: ``` #includeFILE *fp = fopen("in.txt","r"); // 打开一个供读取数据的文件in.txt。 ``` 其中函数的第一个参数是拟打开文件的路径和名字,可以包含相对路径或者绝对路径,如上面程序中就是打开当前目录下的`a.txt`文件。第二个参数是打开方式,`fopen`函数可以使用的打开方式如下表: | 打开方式| 描述| | -------- | -------- | | r | 打开一个供读取数据的文件| | w | 建立或打开一个供写入数据的文件,如果该文件已经存在,则废弃文件内容| | a | 建立或打开一个供写入数据的文件,如果文件已经存在,则写入的数据将追加到文件的尾部| | r+ | 打开一个已存在的文件,该文件可以写入和读出数据| | w+ | 建立或打开一个可供读和写的文件,如果文件已存在,则废弃文件内容| | a+ | 建立或打开一个可供读和写的文件,如果文件已存在,则写入的数据追加到文件的尾部| | b | 打开一个二进制文件| 如果文件打开成功,函数 `fopen `将返回一个指向` FILE` 结构的指针,该指针指向的 `FILE` 结构管理了被打开的那个文件。 如果文件打开失败(如打开一个不存在的文件用于读),那么该函数将返回` NULL`。上面的程序将返回值赋值给`FILE*`的指针 `fp` ,之后就可以通过` fp `来操作打开的文件了。 **读写文件** 1. 从文本文件中读取一个字符可以使用 `fgetc` 函数: `int fgetc(FILE *stream);` 该函数表示从文件指针` stream` 指向的文件的当前位置读取一个字符,并以` int` 类型返回。 2. 从文本文件读取一行可以使用 `fgets `函数: `char *fgets(char *string, int n, FILE *stream);` 该函数表示从文件指针 `stream `指向的文件的当前位置开始读取字符串,直到遇到换行符(读入该换行符),或到达文件结束位置,或读取了` n-1` 个字符。读取的字符串存入 `string` 所指的内存单元中,并在所有读取的字符之后添加字符串结束标记`\0`。 如果读取成功,函数返回` string`,如果出错或读取前已经到达了文件结束的位置,将返回` NULL`。 3. 从文本文件中进行格式化读取可以使用` fscanf `函数 `int fscanf(FILE *stream, const char *format [,argument]...);` 该函数的功能是从指定文件中将数据按照格式控制串` format `读出并转换成相应的类型以存入对应的参数中。如果读取成功,该函数返回转换成功的参数的个数,如果出错或读取前已经到达了文件结束的位置,将返回文件结束标志 `EOF`。 函数` fscanf `与 `scanf `函数非常相似,只是` fscanf` 函数多了一个参数 `stream` 以指向要读取数据的文件。 4. 输出格式化数据到文本文件中可以使用 `fprintf `函数: `int fprintf(FILE *stream, const char *format [,argument]…);` 该函数的功能是将数据按照格式控制串 `format` 写入到文件指针` stream `指向的文件中。如果写入成功,函数返回写入的字节数,否则返回一个负数表示错误。 函数` fprintf `与` printf `函数相似,只是 `fprintf `函数多了一个参数 `stream `以表示要写入数据的文件。 **关闭文件** 使用` fclose `函数就可以把缓冲区内最后剩余的数据输出到内核缓冲区,并释放文件指针和有关的缓冲区。 函数原型为: `int fclose(FILE *fp);` 如果流成功关闭,`fclose `返回`0`,否则返回` EOF`(`−1`)。(如果流为`NULL`,而且程序可以继续执行,`fclose `设定 `error number `给 `EINVAL`,并返回` EOF`。) 例如: ``` #include int main(){ FILE *fp; fp = fopen("out.txt", "w"); fprintf(fp, "%s", "www.educoder.net"); fclose(fp); return(0); } ``` ### 编程要求 实现从已有的当前目录下的文件`in.txt`中读取并解析出其中的数值,并将结果写到当前目录下的文件`out.txt`中的功能,具体要求如下: 文件`in.txt`中包含各种字符,但只有数字字符是有效的,提取其中的数字字符,将每3个数字组成一个整数; 写到文件`out.txt`中,每个整数之间用一个空格分开。读取过程中,如果`in.txt`中最后剩下不到3个数字字符,则将剩下的1个或者2个数字字符组成一个整数。 例如:`in.txt`中的内容是`1j3j5sd0msd454ss3msd563`,则抽取出来写入文件`out.txt`的内容应该是`135 45 435 63`(第二个整数是由045三个数字组成,所以是45)。 #### 输入样例1: in.txt文件内容: ```in q12h44h67k854ksd923823sf83wd38457sd433ds, ``` #### 输出样例1: out.txt文件内容: ```out 124 467 854 923 823 833 845 743 3 ``` #### 输入样例2: in.txt文件内容: ```in 1212121212343434343445454545450000005656565665dfsd455 ``` #### 输出样例2: out.txt文件内容: ```out 121 212 121 234 343 434 344 545 454 545 0 0 565 656 566 545 5 ``` 答案: