Linux文件编程应用

目录

一、实现cp命令

二、修改程序的配置文件

三、写一个整数/结构体到文件

1.写一个整数到文件

2.写一个结构体到文件

四、写结构体数组到文件


我们学习了文件编程的常用指令以及了解文件编程的基本步骤后,试着来写一些程序实现某些功能。(没有学过的见我的上一篇文章Linux文件编程(打开/创建&写入&读取&光标移动))

一、实现cp命令

我们可以在终端输入“cp 源文件 目标文件”,表示将源文件复制到目标文件(没有则创建)。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
示例:

可以看到一开始是没有demo7.c这个文件的,使用cp指令后创建了demo7.c,并且两个文件内容一样。 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -在编写程序之前,我们需要了解main函数的参数,完整的main函数原型为:

#include <stdio.h>int main(int argc, char **argv);

怎么理解这两个参数,拿上面的“cp demo4.c demo7.c”举例,我们假设我们已经把程序写好了,那么在终端上我们会输入“./a.out demo4.c demo7.c”以实现和cp指令同样的操作,那么这个argc就是从第一个文件名开始数,一共有多少个文件,argc就是文件的个数;
        argv是一个二级指针,可以理解成指针里的每一项都是一个数组,如果不理解其含义,还是拿上面的举例,argv[0]="./a.out",argv[1]="demo4.c",argv[2]="demo7.c",
我自己理解就是将文件名(含双引号)存到argv数组里面。

利用main函数的参数,我们可以把文件的路径传到程序里去,自然就可以通过对文件的读写操作来实现cp指令,讲到这里大家应该都有思路了。

代码实现:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main(int argc, char **argv)
{int fdSrc;//源文件的文件描述符int fdDes;//目标文件的文件描述符char *readBuf=NULL;if(argc != 3){printf("Pararm error\n");exit(-1);//参数不正确就退出程序}fdSrc = open(argv[1],O_RDWR);int size = lseek(fdSrc,0,SEEK_END);//用lseek函数计算源文件的大小lseek(fdSrc,0,SEEK_SET);//在读之前记得将光标复位!!!readBuf=(char *)malloc(sizeof(char)*size + 8);//根据源文件的大小来给readBuf分配内存空间int n_read = read(fdSrc,readBuf,size);//这里不获得返回值也可以fdDes = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);//得到目标文件的文件描述符int n_write = write(fdDes,readBuf,strlen(readBuf));//同理read函数close(fdSrc);close(fdDes);return 0;
}

 这里有几点要注意的:
1.文件光标位置,在进行读写操作之前,确认光标处于正确的位置。
2.打开文件后必须关闭文件,避免造成数据损坏。
3.在打开目标文件获得其文件描述符时,我们在第二个参数又或上了O_TRUNC,这个参数表示,如果目标文件中原本有内容,会将其全部清除。这样就会避免复制完后,文件本来的内容还存在的情况发生。

(我们不仅能将某个文件拷贝到当前所处文件夹,还能指定文件的绝对路径,拷贝到其他文件夹去)


二、修改程序的配置文件

这里事先创建了TEST.config文件,内容如下

我们想通过程序来修改里面的参数,将LENG改成5。

代码实现:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main(int argc, char **argv)
{int fdSrc;char *readBuf=NULL;if(argc != 2){printf("Pararm error\n");exit(-1);}fdSrc = open(argv[1],O_RDWR);int size = lseek(fdSrc,0,SEEK_END);lseek(fdSrc,0,SEEK_SET);readBuf=(char *)malloc(sizeof(char)*size + 8);int n_read = read(fdSrc,readBuf,size);
/*以上代码和实现cp命令相比,main函数的参数只有两个,也就是说不需要目标文件我们只改变配置文件里面的数据*/char *p = strstr(readBuf,"LENG=");//用strstr函数,会返回'L'的地址。if(p == NULL){printf("not found\n");exit(-1);}p = p+strlen("LENG=");//将指针指向'='后面一位*p = '5';//注意文件里面存的都是字符串,所以要用字符给指针所指向的内存赋值int n_write = write(fdSrc,readBuf,strlen(readBuf));//最后将修改好的Buf写入原先的文件即可close(fdSrc);return 0;
}

这个应用主要是对strstr函数的调用,拿上面代码举例,函数会在readBuf字符串里面找到"LENG="这个字符串,并且返回要找的这个字符串的首地址,就是'L'的地址,要修改等号后面的字符,用strlen计算目标字符串的大小即可。(这种方法只能修改一个字符,如果原本的参数有两位,那么这个程序只能修改等号后面的一位)


三、写一个整数/结构体到文件

我们之前对文件的操作都是基于字符串,如果要向文件写入一个结构体该如何操作?

1.写一个整数到文件

我们先来实现写入一个整数的操作;我们先看write函数的原型

可以看到第二个参数是个无类型的指针,也就是说我们只要传进去的是个地址就可以。

代码实现: 

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main()
{int fd;int data=100;int data2=0;fd = open("./file1",O_RDWR);int n_write = write(fd,&data,sizeof(int));//传入data的地址,长度为int类型的地址长度lseek(fd,0,SEEK_SET);//光标复位int n_read = read(fd,&data2,sizeof(int));printf("read %d\n",data2);//读出来后验证是否成功写入close(fd);return 0;
}

代码还是比较简单的,结果也和我们预期的一样

2.写一个结构体到文件

根据上面的代码,只要稍作改进就可以实现写入结构体到文件

代码实现: 


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>struct Test{int a;char c;
};int main()
{int fd;struct Test data={100,'a'};struct Test data2;fd = open("./file1",O_RDWR);int n_write = write(fd,&data,sizeof(struct Test));	lseek(fd,0,SEEK_SET);int n_read = read(fd,&data2,sizeof(struct Test));printf("read %d,%c\n",data2.a,data2.c);close(fd);return 0;
}

定义一个结构体,用定义的结构体类型去定义data变量,那么用write和read函数时同样传入的是data的地址,长度为定义的结构体类型的指针的长度。

四、写结构体数组到文件

话不多说,直接上代码

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>struct Test{int a;char c;
};int main()
{int fd;struct Test data[2]={{100,'a'},{101,'b'}};struct Test data2[2];fd = open("./file1",O_RDWR);int n_write = write(fd,&data,sizeof(struct Test)*2);//数组有两个元素,x2就行了	lseek(fd,0,SEEK_SET);int n_read = read(fd,&data2,sizeof(struct Test)*2);printf("read %d,%c\n",data2[0].a,data2[0].c);printf("read %d,%c\n",data2[1].a,data2[1].c);close(fd);return 0;
}

可以看到其实和前面几个代码差不多,只不过在原先的基础上扩展而来。 

打印结果:        

        这些应用程序都是一步一步慢慢扩展来的,该文章也是对c语言的知识做一些巩固和加强,这里面很多操作都涉及到了地址,对地址的概念和对指针的操作还是相当重要的,要熟练的运用指针,才能在程序的道路上畅通无阻。 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记录一次微信小程序申诉定位权限过程

1 小程序接到通知&#xff0c;检测到违规&#xff0c;需要及时处理&#xff0c;给一周的缓冲时间&#xff0c;如果到期未处理&#xff0c;会封禁能力&#xff08;2023-11-17&#xff09; 2 到期后&#xff0c;仍未处理&#xff0c;封禁能力&#xff08;2023-11-24&#xff09; …

【04】微服务通信组件Feign

1、项目中接口的调用方式 1.1 HttpClient HttpClient 是 Apache Jakarta Common 下的子项目&#xff0c;用来提供高效的、最新的、功能丰富的支持 Http 协议的客户端编程工具包&#xff0c;并且它支持 HTTP 协议最新版本和建议。HttpClient 相比传统 JDK 自带的 URLConnectio…

打印任务无法删除怎么办?

在删除打印任务的时候&#xff0c;你可能会遇到这样的情况&#xff0c;当我们想把打印任务取消的时候&#xff0c;却一直显示正在删除&#xff0c;而过了很久还没有取消掉&#xff0c;下面就分享一下处理这个问题的方法。 1、停止打印服务&#xff0c;按WinR键打开运行对话框&a…

Unity WebGL 嵌入前端网页并通信

1. 前言 最近在做项目时遇到需要将 UnityWebGL 嵌入到网页中去&#xff0c;且需要点击网页中的按钮 UnityWebGL 可以做出响应。新建项目部分直接略过 2. 最终效果 3. 基础设置 设置导出平台为WebGL 在Player Settings -> Publishing Settings 中勾选 Data Caching 和Deco…

《Windows API每日一练》9.1.5 自定义资源

自定义资源&#xff08;Custom Resources&#xff09;是在 Windows 程序中使用的一种资源类型&#xff0c;用于存储应用程序特定的数据、图像、音频、二进制文件等。通过自定义资源&#xff0c;开发者可以将应用程序所需的各种资源文件集中管理和存储&#xff0c;便于在程序中访…

imx6ull/linux应用编程学习(17)利用mqtt上传开发板数据,和控制开发板led(基于正点)

1.关于如何创建自己的服务器&#xff0c;可看上篇文章 imx6ull/linux应用编程学习&#xff08;16&#xff09;emqx &#xff0c;mqtt创建连接mqtt.fx-CSDN博客 2.实现任务&#xff1a;&#xff08;正点原子教程源码改&#xff09; (1)用户可通过手机或电脑远程控制开发板上的…

小白的OS Copilot 产品测评

背景 通过群友介绍才知OS Copilot 。不想错过任何优秀的AI产品。随着互联网的发展和时代的进步&#xff0c;要紧跟时代&#xff0c;了解市面上的优秀的AI科技产品。 OS Copilot 产品体验评测 1&#xff09;您的角色是什么&#xff1f;开发、运维、学生&#xff1f;如果使用O…

类和对象——【const成员】【static成员】【友元】【内部类】

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件iostream的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

css文字自适应宽度动态出现省略号...

前言 在列表排行榜中通常会出现的一个需求&#xff1a;从左到右依次是名次、头像、昵称、徽标、分数。徽标可能会有多个或者没有徽标&#xff0c;徽标长度是动态的&#xff0c;昵称如果过长要随着有无徽标进行动态截断出现省略号。如下图布局所示&#xff08;花里胡哨的底色是…

若依vue集成electron实现打包exe应用程序

一、修改package.json文件,加入相关依赖和配置 {"name": "ruoyi","version": "3.8.6","description": "若依管理系统","author": "若依","license":

分层图最短路,CF 1725M - Moving Both Hands

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1725M - Moving Both Hands 二、解题报告 1、思路分析 题意看似很简单&#xff0c;就是问我们两个人分别处于1, p两个点上&#xff0c;二者同时出发&#xff0c;相遇时二者所用路径之和的最小值 不难想到求…

Git协作

文章目录 Git协作冲突冲突的发生情况解决冲突如何处理冲突 1 分支1.1 什么是Git分支1.2 创建分支 2 切换分支2.1 指向分支2.2 暂存分支切换分支与未提交更改的处理使用 Stash 临时保存更改Stash 的工作原理&#xff1a;场景设定使用 Git Stash 3 远程分支3.1 快进合并快进合并的…

Qt/QML学习-定位器

QML学习 定位器例程视频讲解代码 main.qml import QtQuick 2.15 import QtQuick.Window 2.15Window {width: 640height: 480visible: truetitle: qsTr("positioner")Rectangle {id: rectColumnwidth: parent.width / 2height: parent.height / 2border.width: 1Col…

Qt基础控件总结—多页面切换(QStackWidget类、QTabBar类和QTabWidget类)

QStackedWidget 类 QStackedWidget 类是在 QStackedLayout 之上构造的一个便利的部件,其使用方法与步骤和 QStackedLayout 是一样的。QStackedWidget 类的成员函数与 QStackedLayout 类也基本上是一致的,使用该类就和使用 QStackedLayout 一样。 使用该类可以参考QStackedL…

iPhone数据恢复篇:在 iPhone 上恢复找回短信的 5 种方法

方法 1&#xff1a;检查最近删除的文件夹 iOS 允许您在 30 天内恢复已删除的短信。您需要先从“设置”菜单启用“过滤器”。让我们来实际检查一下。 步骤 1&#xff1a;打开“设置” > “信息”。 步骤 2&#xff1a;选择“未知和垃圾邮件”&#xff0c;然后切换到“过滤…

如何将若依vue升级到springboot3.x?

为了确保项目符合要求,Spring Boot 3.x 要求Java版本为17或更高。 1、修改根目录下的pom.xml文件 <!-- java.version版本8更换为17 --> <java.version>17</java.version><!-- 新增节点 --> <mybatis-spring-boot.version>3.0.3<

SpringMVC(3)——SpringMVC注解实战

前言 SpringMVC&#xff08;2&#xff09;——controller方法参数与html表单对应&#xff08;请求参数的绑定&#xff09; 上篇博客我们提到了controller方法的参数与html表单之间的对应关系 但是这种对应关系有很多缺点&#xff1a; 传递参数只能放在request的body当中&am…

极狐Gitlab使用(2)

目录 1. Gitlab命令行修改管理员密码 2. Gitlab服务管理 3. 公司的开发代码提交处理流程 4. Gitlab 备份与恢复 数据备份 测试数据恢复 5. 邮箱配置 1. Gitlab命令行修改管理员密码 [roottty01 ~]# gitlab-rails console -e production # 启动GitLab的Rails控制…

windows USB 设备驱动开发-USB电源管理(一)

符合通用串行总线 (USB) 规范的 USB 设备的电源管理功能具有一组丰富而复杂的电源管理功能。 请务必了解这些功能如何与 Windows 驱动程序模型 (WDM) 交互&#xff0c;特别是 Microsoft Windows 如何调整标准 USB 功能以支持系统唤醒体系结构。 基于内核模式驱动程序框架的 US…

2024年06月CCF-GESP编程能力等级认证Python编程四级真题解析

本文收录于专栏《Python等级认证CCF-GESP真题解析》,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 一、单选题(每题 2 分,共 30 分) 第 1 题 小杨父母带他到某培训机构给他报名参加CCF组织的GESP认证考试的第1级,那他可以选择的认证语言有几种?( ) A. 1 B. 2 C…