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

本文主要是介绍C语言-有两个磁盘文件A和B,各存放一行字母,今要求把这两个文件的信息合并(按字母顺序排列),输出到一个新文件C中去-深度代码解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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函数使用方法

这篇关于C语言-有两个磁盘文件A和B,各存放一行字母,今要求把这两个文件的信息合并(按字母顺序排列),输出到一个新文件C中去-深度代码解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1105755

相关文章

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

java之Objects.nonNull用法代码解读

《java之Objects.nonNull用法代码解读》:本文主要介绍java之Objects.nonNull用法代码,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录Java之Objects.nonwww.chinasem.cnNull用法代码Objects.nonN

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI