C语言-有两个磁盘文件A和B,各存放一行字母,今要求把这两个文件的信息合并(按字母顺序排列),输出到一个新文件C中去-深度代码解析

embedded/2024/12/23 1:19:38/

1、题目要求

有两个磁盘文件A和B,各存放一行字母,今要求把这两个文件的信息合并(按字母顺序排列),输出到一个新文件C中去

2、准备工作

问题1:为什么不需要手动创建C.txt文件?

答:根据题意我们可知,我们需要调用fopen函数以只读方式打开A.txt和B.txt文件,只读方式打开文件要求文件必须提前存在,而C.txt文件需要以写入方式打开,如果文件不存在,会自动创建一个C.txt文件。

参考:fopen函数使用方法

3、具体程序

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
void openFile(FILE **fpa,FILE **fpb, FILE **fpc)  //打开文件函数
{*fpa = fopen("A.txt", "r");if (*fpa == NULL){printf("打开文件A失败\n");exit(1);}*fpb = fopen("B.txt", "r"); if (*fpb == NULL){printf("打开文件B失败\n");exit(1);}*fpc = fopen("C.txt", "w");if (*fpc == NULL){printf("打开文件c失败\n");exit(1);}
}
void closeFile(FILE* fpa, FILE* fpb, FILE* fpc)//关闭文件函数
{fclose(fpa);fclose(fpb);fclose(fpc);
}
void GetBufferChar(FILE* fpa, FILE* fpb, char* buffer)//连接字符串函数
{fgets(buffer, 1024, fpa);//从A文件读入数据int len = strlen(buffer);fgets(buffer + len, 1024, fpb);//从B文件读入数据
}
void SortBufferChar(char* buffer)
{int n = strlen(buffer);for (int i = 0; i < n - 1; i++){for (int j = 0; j < n - i - 1; j++){if (buffer[j] > buffer[j + 1]){char temp = buffer[j];buffer[j] = buffer[j + 1];buffer[j + 1] = temp;}}}
}
void SaveFile(FILE* fpc, char* buffer)
{fputs(buffer, fpc);
}
int main()
{FILE* fpa, *fpb, *fpc;char buffer[1024] = { 0 };openFile(&fpa, &fpb, &fpc);//打开全部文件,A,B以只读方式,C以写入方式GetBufferChar(fpa, fpb, buffer);//连接字符串printf("数据相连的结果是\n%s\n",buffer);SortBufferChar(buffer);//字符串排序printf("排序后字符串结果是\n%s\n",buffer);SaveFile(fpc, buffer);closeFile(fpa, fpb, fpc);return 0;
}

4、代码深度解析

4.1 main函数:

创建三个FILE类型指针,和字符型数组buffer,并通过5个函数实现功能;

4.2 openFile函数

openFile(FILE **fpa,FILE **fpb, FILE **fpc)

函数参数为二级指针,即FILE类型地址的地址(指针的指针)

问题2:为什么要拿二级指针而不是一级指针

答:在主函数中,我么创建了三个FILE类型的指针变量,但是并没有给定指向,那么最开始的三个FILE类型的指针变量需要我们在openFile函数中给定指向。具体是怎么做的呢?首先,我们知道实参向形参的数据传递是“值传递”,单向传递,如果将一级指针传给openFile函数,然后在openFile函数中将一级指针指向fopen函数即以下代码,那么根据值传递的特点,main函数中的File类型指针实际上根本没有指向fopen函数,这显然是错误的。那么如何让main函数中的FILE类型指针指向fopen函数呢?这就需要二级指针发挥作用了,我们将二级指针作为openFile函数参数,通过解引用的方式将二级指针的值(解引用二级指针,得到二级指针的值,即一级指针)指向fopen函数,这相当于在main函数中将三个FILE类型指针初始化了,这显然是可行的,因此要拿二级指针而不是一级指针。

参考:C语言实参和形参数据传递的特点及使用技巧

void openFile(FILE *fpa,FILE *fpb, FILE *fpc)  //打开文件函数(错误写法)
{fpa = fopen("A.txt", "r");if (fpa == NULL){printf("打开文件A失败\n");exit(1);}fpb = fopen("B.txt", "r"); if (fpb == NULL){printf("打开文件B失败\n");exit(1);}fpc = fopen("C.txt", "w");if (fpc == NULL){printf("打开文件c失败\n");exit(1);}
}
int main()
{FILE* fpa, *fpb, *fpc;openFile(fpa, fpb, fpc);//(错误写法)return 0;
}

4.3 closefile函数

closeFile(FILE* fpa, FILE* fpb, FILE* fpc)

此函数在文件操作完成后,将各文件关闭。

参考:fclose函数使用方法

4.4 GetBufferChar函数

GetBufferChar(FILE* fpa, FILE* fpb, char* buffer)

该函数为字符串连接函数,用于将A.txt和B.txt文件中的字符串连接并保存到字符数组中,在main函数中直接将字符数组buffer的数组名作为参数,则数组名为指向字符数组首元素的指针。通过fgets函数从文件流fpa中取出最多1024-1个字符赋值给buffer字符数组进行顺序保存(fgets函数功能),保存完文件A.txt中的字符后,计算buffer数组中的字符长度,以供B.txt文件中的字符紧跟在已经存入buffer字符数组中A文件字符的后面,实现两文件字符在buffer字符数组中实现连接。

参考:fgets函数的使用方法

问题3:什么是文件流?

答:文件流是一个抽象的概念,我们可以这样理解,FILE类型的指针通过fopen函数指向一个文件后,FILE类型的指针变量就能够称为文件流了,我们可以通过文件流实现各种文件操作。

4.5 SortBufferChar函数

SortBufferChar(char* buffer)

该函数实现将buffer数组中已经连接好的字符重新排序,采用的是冒泡排序

参考:字符串排序方法

4.6 SaveFile函数

SaveFile(FILE* fpc, char* buffer)

此函数将buffer中排好序的字符最终写入到文件C.txt中

参考:fputs函数使用方法


http://www.ppmy.cn/embedded/100462.html

相关文章

基础算法--高精度数据(2)

本节继续上节内容&#xff1a;高精度数据处理。本节主题是回文数。 一、判断方法 什么是回文数&#xff1a;一个数字从左往右读与从右往左读是一样的&#xff0c;那么这个数就是回文数。例如&#xff1a;121&#xff0c;6226&#xff0c;3333、12121等。简单的判断回文数的方…

Mysql 报错 1365 - Division by 0

Mysql 报错 1365 - Division by 0 解决办法 直接运行一下命令 set sql_mode(select REPLACE(sql_mode,ERROR_FOR_DIVISION_BY_ZERO,));

【Electron】桌面应用开发启动直接打开一个网址或者浏览器打开一个网址

【Electron】桌面应用开发启动时直接打开一个网址或者跳转浏览器打开一个网址 前一篇有写过 Electron 桌面应用开发快速入门到打包Windows应用程序 但是现在需要程序打开的时候直接打开一个链接&#xff0c;在程序的窗口打开或者直接跳转浏览器打开 一、启动时直接打开一个网…

AgentQ,超越人类的人工智能代理

MultiOn 宣布推出一款新代理AgentQ&#xff0c;这是一款令人惊叹的产品&#xff0c;它整合了我最近一直在讨论的大部分内容&#xff1a;将 LLM 与搜索相结合。 但这个经纪人很特殊。 与其他代理不同的是&#xff0c;由于巧妙地使用了对齐技术&#xff0c;该代理可以从好的和坏的…

【Docker】Docker学习04 | dockerfile的编写

本文首发于 ❄️慕雪的寒舍 dockerfile是构建docker镜像的基础&#xff0c;它规定了一系列语法&#xff0c;让我们可以在某个基础镜像之上&#xff0c;添加自己需要的操作&#xff0c;打包出一个自己的镜像。 1. dockerfile基本语法 下面是dockerfile的基本语法和其对应的功能…

OSPF路由配置--单区域

目录 因为OSPF有很多重要的特殊区域和内容,所以划分为多篇博客来配置 一. 实验拓扑图 二. 实验配置 三. 实验验证: 因为OSPF有很多重要的特殊区域和内容,所以划分为多篇博客来配置 不理解OSPF路由动态协议的可以回顾一下OSPF详解&#xff0c;下这一系列的实验都不再做解…

34 增加系统调用(3)

首先是 在GDT中添加 系统调用的内容&#xff1a; 然后是汇编中实现 syscall_hander 然后是使用C语言函数 实现在屏幕上显示字符。 然后是在 任务中调用这个函数。 然后 sys_show 去调用 系统调用。 在进行系统调用前需要 保存现场。 系统调用之后需要 释放现场。 为了保证在系统…

javascript写一个本地数据库支持SQL查询-SAAS本地化未来之窗行业应用跨平台架构

一、sql语句优点 数据查询灵活&#xff1a; 可以通过各种条件进行精确查询&#xff0c;比如使用 WHERE 子句指定特定的筛选条件&#xff0c;轻松从庞大的数据库中获取所需数据。例如&#xff0c;“SELECT * FROM employees WHERE department Sales” 可以快速找出销售部门的所…