-->
当前位置:首页 > 题库

主观题:文本文件读写

Luz5年前 (2021-06-19)题库631
### **任务描述:**
本关任务:编写函数,该函数从已有的当前目录下的文件`in.txt`中读取并解析出其中的数值,并将结果写到当前目录下的文件`out.txt`中。

### **相关知识:**
**文件**

文件是存储在某种长期储存设备(磁盘、光盘等)上的一段数据流。C 语言中把文件看成一个有序的字节流,每个文件都以文件结束标志( `EOF `)结束。

下图是包含` n` 个字节的文件内容:

![Snipaste_2021-04-11_13-13-18.png](~/30465e43-1e9b-4aef-ad4b-903a39fe6ef3.png)

磁盘文件由操作系统中的文件系统统一管理,也只有文件系统才能直接操作文件。所以编写 C 程序来操作文件实际上是需要调用文件系统的接口函数来实现,我们学习文件的操作也就是学习一些 C 语言库中提供的函数。

**文件类型**

C 语言在对文件进行操作时,将文件分为**文本文件**和**二进制文件**。
1. 文本文件:指可以用任何文字处理程序阅读和编辑的简单 ASCII 文件;
1. 二进制文件:指一般含有特殊的格式或计算机代码,如图形文件和可执行文件等。

**文件的操作**

C 语言中对文件的操作一般分为三个步骤:**打开文件**、**读写文件**、**关闭文件**。

* 打开文件

打开文件后,操作系统为文件建立一个文件控制结构(文件控制块),并在内存中建立一个缓冲区,该缓冲区的数据对应文件的数据,之后的文件读写操作实际上是在缓冲区中进行。

* 读写文件

通过文件控制块实现文件的输入输出。

* 关闭文件

将文件缓冲区中的数据写回到磁盘文件中,并释放文件控制块。

**操作文件的函数**

用 FILE 结构操作文件是 C 语言提供的文件操作方式,只要包含头文件stdio.h就能使用文件操作的相关函数。下面就给大家介绍一些函数的使用。

**打开文件**

`fopen `是`stdio.h`提供的文件打开函数。

如下面的程序可以打开一个文件用于读:

```
#include 
FILE *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
```






答案: