Linux初学第三天<write/read练手小应用的编程>

实现cp 复制指令

cp指令: 复制一个文件,并对复制后的文件进行重命名;
用法:

***@Embed_Learn:~$ cp demo5.c demo6.c //复制一个demo5.c 为demo6,c

除了名字不一样之外,demo6.c和demo5.c的内容一样。
我们利用write/read 函数来写一个小应用来实现和cp 指令一样的效果。

C语言参数输入

在正式编程之前,我们应该要熟悉C语言的参数输入,也就是当运行程序的时候,如何输入文件名,即上面提到cp 指令之后跟着的 demo5.cdemo6.c 。我们所写出来的程序运行的时候,也应该是类似cp 一样的操作,
比如:./a.out demo5.c demo6.c 。

demo5.cdemo6.c 该怎么输入呢?其实很简单,给main函数传递参数就行了,我们可以写一个测试程序来看看:

#include <stbio.h>
int main(int argv,char **argc)//传递参数,argv为参数个数  **argc为二级指针,即指针数组
{
        if(rgv!=3){                      //判断输入是否是三个
                printf("params error!");//如果不是则提示错误
                exit(-1);               //结束程序               
        }
        printf("params argv:%d\n",argv);//打印参数个数
        printf("params argc1:%s\n",argc[0]);//第一个参数
        printf("params argc2:%s\n",argc[1]);//第二个参数
        printf("params argc3:%s\n",argc[2]);//第三个参数

        return 0;
}

运行结果如下:
在这里插入图片描述
可以看到,运行 ./a.out Src Der 后正确输出了这三个参数,至此我们就可以开始编程了。

编程思路

Created with Raphaël 2.2.0开始传递参数main(int argv,char **argc)打开文件(open)文件名:argc[1]读取文件内容(read)存放到*buf中打开或者创建新的文件(文件名应该是argc[2])把*buf中的内容写入新的文件中关闭两个文件结束

详细代码:

#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 fd_Src,fd_Des;//定义文件描述符
        char *Scr_Buf=NULL;//定义文件内容缓存区
        if(argc!=3){
                printf("params error!\n");
                exit(-1);
        }
        fd_Src=open(argv[1],O_RDWR);//打开已经存在的文件
        int Src_Size=lseek(fd_Src,0,SEEK_END);//读取该文件的大小
        lseek(fd_Src,0,SEEK_SET);			  //把光标设置到文件头部,方便下次读取

        Scr_Buf=(char *)malloc(sizeof(char)*Src_Size+8);//为指针分配合适的内存空间
        int n_read=read(fd_Src,Scr_Buf,Src_Size);		//读取argv[1]的内容
//       ssize_t write(int fd, const void *buf, size_t count);  
        fd_Des=open(argv[2],O_RDWR|O_CREAT,0600);		//打开并创建一个新的文件

        int n_write=write(fd_Des,Scr_Buf,n_read);		//把读取的内容写入刚刚创建的文件中
        if(n_write!=-1){		//判断是否写入失败
                printf("write %d byte to file\n",n_write);//打印写入数据的大小
        }
        close(fd_Src|fd_Des);	//关闭两个文件
        return 0;
}

运行结果:
在这里插入图片描述
可以看到,我们在运行./mycp demo4.c new1.c后,看到打印:wrie 909 byte to file,证明我们成功的写入了,程序运行正确。

实现修改配置文件参数

功能说明: 有一个 .config 的配置文件,里面有如下配置信息:

NAME=6
SPEED=10
LENG=36
TIME=75

编写一个能够实现修改某个参数的值的小应用,比如运行 ./rev Test.config NAME 36 就是把Test.config中的NAME 的值改为36。

编程思路

Created with Raphaël 2.2.0开始open一个文件用 strstr函数找到需要修改的参数定位到要修改参数的位置修改参数的值把修改后的参数写入配置文件关闭文件结束

在编程过程中需要注意需要修改的参数的地址不能改变,否则会破坏配置文件:
首先创建一个名为Test.config 的文件,在文件写一些参数;就拿上面所说的参数为例。
在这里插入图片描述
Test.config中的原始内容如下:
在这里插入图片描述

详细代码:

#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 fd_Src,i;
        char *Scr_Buf=NULL;
        char *p=NULL;
        if(argc!=4){
                printf("params error!\n");
                exit(-1);
        }
        fd_Src=open(argv[1],O_RDWR,0600);//打开一个配置文件

        int Src_Size=lseek(fd_Src,0,SEEK_END);//计算文件的大小
        lseek(fd_Src,0,SEEK_SET);				//光标定位到文件头
        Scr_Buf=(char *)malloc(sizeof(char)*Src_Size+8);//分配适合的空间
        int n_read=read(fd_Src,Scr_Buf,Src_Size);//读取文件内容
        printf("read:%s",Scr_Buf);//打印读取信息
        p=strstr(Scr_Buf,argv[2]);//查找需要修改的参数
        if(p==NULL){
                printf("no found!\n");//如果找不到,则打印错误信息
                exit(-1);          //然后结束程序
        }
        p=p+strlen(argv[2])+1;//指针根据参数来移位,+1是 为了移到“=”的后面
        *p='\0';//“=”的后面的值全部清掉
        int j=(int)strlen(argv[3]);//获取修改值得字符串长度
        for(i=0;i<j;i++){          
                *p=*argv[3];      //开始赋值
                argv[3]++;        //赋值后,往后位移一位
                p++;			  //p 也应该往后移	
        }
 		lseek(fd_Src,0,SEEK_SET);//光标重新移到文件头,这样可以覆盖原来的信息
        int n_write=write(fd_Src,Scr_Buf,strlen(Scr_Buf));//开始写入
        printf("write:%s\n",Scr_Buf);//打印写入的信息
        close(fd_Src);//关闭文件
        return 0;
}

需要注意的是,在赋值的时候,我们用的是取内容运算符 ,而不是直接 p=argv[3] ,这是因为指针p的地址是和Src_Buf 的其中一个参数的地址是一样的,如果我们 p=argv[3] 的话,会改变p的地址,造成Test.config的配置信息没有改变,就达不到我们的目的 。而使用 *p的话,就不会改变地址,改的其中的内容而已,这样就连带Scr_Buf的同地址的内容一起修改了。

运行结果:

在这里插入图片描述


版权声明:本文为qq1140920745原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。