Linux文件编程应用

news2024/9/27 17:24:46

目录

一、实现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.coloradmin.cn/o/1920026.html

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

相关文章

Java设计模式的7个设计原则

Java设计模式的7个设计原则是面向对象设计领域中的重要指导方针&#xff0c;它们旨在提高软件系统的可维护性、可扩展性、可复用性和灵活性。以下是这7个设计原则的详细解释&#xff1a; 1. 开闭原则&#xff08;Open-Closed Principle, OCP&#xff09; 定义&#xff1a;一个…

体验一下智能指针的强大

课程总目录 文章目录 一、智能指针基础知识二、不带引用计数的智能指针auto_ptrscoped_ptrunique_ptr 三、带引用计数的智能指针模拟实现一个带引用计数的智能指针shared_ptr交叉引用问题 四、多线程访问共享对象的线程安全问题五、智能指针删除器六、建议用make_shared代替sha…

如何找工作 校招 | 社招 | 秋招 | 春招 | 提前批

马上又秋招了&#xff0c;作者想起以前读书的时候&#xff0c;秋招踩了很多坑&#xff0c;但是第一份工作其实挺重要的。这里写一篇文章&#xff0c;分享一些校招社招的心得。 现在大学的情况是&#xff0c;管就业的人&#xff0c;大都是没有就业的辅导员&#xff08;笔者见过…

JavaWeb(一:基础知识和环境搭建)

一、基本概念 1.前言 JavaWeb&#xff1a;在Java中&#xff0c;动态web资源开发网页的技术。 web应用分两种&#xff1a;静态web资源和动态web资源 Ⅰ. 静态web资源&#xff08;如html 页面&#xff09;&#xff1a; 指web页面中的数据始终是不变。 所有用户看到都是同一个…

基于YOLOV8的数粒机-农业应用辣椒种子计数计重双标质量解决方案

一:辣椒种子行业背景调查 中国辣椒年产量稳居世界第一,食辣人口超5亿。中国辣椒全球闻名,小辣椒长成大产业,带动全球食品行业腾飞。 在中国,“辣”是不少地方餐桌上的一大特色。从四川的麻辣火锅到湖南的剁椒鱼头再到陕西的油泼辣子面,由南到北,总有食客对辣有着独一份偏…

力扣-回溯法

何为回溯法&#xff1f; 在搜索到某一节点的时候&#xff0c;如果我们发现目前的节点&#xff08;及其子节点&#xff09;并不是需求目标时&#xff0c;我们回退到原来的节点继续搜索&#xff0c;并且把在目前节点修改的状态还原。 记住两个小诀窍&#xff0c;一是按引用传状态…

连接与隔离:Facebook在全球化背景下的影响力

在当今全球化的背景下&#xff0c;Facebook作为全球最大的社交网络平台&#xff0c;不仅连接了世界各地的人们&#xff0c;还在全球社会、经济和文化中发挥着深远的影响。本文将深入探讨Facebook在全球化进程中的作用&#xff0c;以及其对个体和社会之间连接与隔离的双重影响。…

【区块链农场】:农场游戏+游戏

我的酒坊是一款非常受玩家欢迎的经营手游,游戏中你需要合理经营一家酒厂,将其做大做强。通过制定合理的战略,例如新建厂房,并采用传统工艺制作,针对不同的人群研制多重口味。

Ubuntu与Windows通过WIFI与以太网口共享网络,Ubuntu与Windows相互ping通,但ping百度失败

Linux开发板&#xff08;正点原子阿尔法_IMX6U&#xff09;与Ubuntu的文件传输SCP 报错 SSH: no matching host key type found. Their offer: ssh-rsa-CSDN博客 前面的文章提到了如何将Ubuntu与Windows通过WIFI共享网络给以太网&#xff0c;从而实现Linux开发板、Ubuntu、Win…

Umi.js 项目中使用 Web Worker

1.配置 Umi.js 在 Umi.js 中&#xff0c;需要通过配置来扩展 Webpack 的功能。在项目根目录下修改 config/config.ts 文件&#xff1a; export default defineConfig({chainWebpack(config) {config.module.rule(worker).test(/\.worker\.ts$/).use(worker-loader).loader(wo…

常见网页问题解决

用edge浏览器打印功能时&#xff0c;出现瞬间或加载几秒后突然闪退情况&#xff0c;本来以为是浏览器出了问题&#xff0c;去重置设置也没有&#xff0c;后来又下载了Chrome浏览器&#xff0c;没想到还是一样&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;想着…

系统服务综合实验

实验需求&#xff1a; 现有主机 node01 和 node02&#xff0c;完成如下需求&#xff1a; 在 node01 主机上提供 DNS 和 WEB 服务dns 服务提供本实验所有主机名解析web服务提供 www.rhce.com 虚拟主机该虚拟主机的documentroot目录在 /nfs/rhce 目录该目录由 node02 主机提供的…

判断链表中是否有环(力扣141.环形链表)

这道题要用到快慢指针。 先解释一下什么是快慢指针。 快慢指针有两个指针&#xff0c;走得慢的是慢指针&#xff0c;走得快的是快指针。 在这道题&#xff0c;我们规定慢指针一次走一步&#xff0c;快指针一次走2步。 如果该链表有环&#xff0c;快慢指针最终会在环中相遇&a…

MySQL数据库基本操作-DDL和DML

1. DDL解释 DDL(Data Definition Language)&#xff0c;数据定义语言&#xff0c;该语言部分包括以下内容&#xff1a; 对数据库的常用操作对表结构的常用操作修改表结构 2. 对数据库的常用操作 功能SQL查看所有的数据库show databases&#xff1b;查看有印象的数据库show d…

02. 存储引擎

1. 前言 在校招或者社招面试中&#xff0c;无论你是 Java 后端、Cpp 后端、Python 后端&#xff0c;面试官都会详细地考察各种语法细节、框架知识&#xff0c;但是大多数候选人入职之后&#xff0c;都会体会到 "面试造火箭&#xff0c;上班拧螺丝"。面试时我们熟悉各…

Python | Leetcode Python题解之第229题多数元素II

题目&#xff1a; 题解&#xff1a; class Solution:def majorityElement(self, nums: List[int]) -> List[int]:cnt {}ans []for v in nums:if v in cnt:cnt[v] 1else:cnt[v] 1for item in cnt.keys():if cnt[item] > len(nums)//3:ans.append(item)return ans

C#绘制阻抗圆图初步

阻抗圆图&#xff0c;或者叫史密斯图&#xff0c;是无线电设计方面用的&#xff1b; 基本的阻抗圆图如下&#xff0c; 下面尝试用C#能不能画一下&#xff1b; 先在网上找一个画坐标的C#类&#xff0c;它的效果如下&#xff1b; 自己再增加一个函数&#xff0c;可以绘制中心在…

【JSP+Servlet+Maven】——优质外卖订餐系统之概论部分

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

PPTP、L2TP、IPSec、IPS 有什么区别?

随着互联网的发展&#xff0c;保护网络通信的安全越来越重要。PPTP、L2TP、IPSec、IPS是常见的网络安全协议和技术&#xff0c;在保护网络通信安全方面发挥着不同的作用和特点。下面介绍PPTP、L2TP、IPSec、IPS之间的区别。 点对点隧道协议&#xff08;PPTP&#xff09;是一种用…

使用大模型进行SQL迁移的实践总结

在现代化的项目管理和运维工作中&#xff0c;利用大模型&#xff08;如ChatGPT&#xff09;处理复杂任务已成为一种高效手段。近期我们在一个项目中尝试利用大模型将MySQL导出的SQL语句迁移为达梦信创数据库格式&#xff0c;通过几轮操作&#xff0c;我们深刻体会到提示词工程的…