【Linux】系统编程之文件(小应用--实现cp复制命令等)

一、实现cp复制命令

1、介绍main函数参数

函数原型:

main (int argc,char *argv[]){...}
main (int argc,char **argv){...}

参数介绍:

(1)argc
argc为整型,用来统计程序运行时发送给main函数的命令行参数的个数,也是数组中字符串的数量。
(2)argv

1、char **argv 分析:首先argv是一个指针变量,argv的指向(*argv)是char *,也就是argv指向的也是一个指针;
*argv的指向(**argv)是char[类比char *p,p的指向(*p)是char] 。
2、char *argv[] 分析:首先argv是一个数组,数组里面的元素是指针变量(char *),数组里元素指向的是char。
为字符串数组,用来存放指向的字符串参数的指针数组,每一个元素指向一个参数

argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数是命令行后面跟的用户输入的参数,各成员含义如下:
argv[0] 指向程序运行的全路径名
argv[1] 指向在DOS命令行中执行程序名后的第一个字符串
argv[2] 指向执行程序名后的第二个字符串
argv[3] 指向执行程序名后的第三个字符串
argv[argc] 为NULL
参考:深度理解char *,char **,char a[],char *[]的区别
示例
代码:

#include <stdio.h>

int main(int argc,char **argv)//main(int argc,char *argv[])
{
        printf("total params : %d\n",argc);
        printf("NO.1 params : %s\n",argv[0]);
        printf("NO.2 params : %s\n",argv[1]);
        printf("NO.3 params : %s\n",argv[2]);
        printf("NO.4 params : %s\n",argv[3]);
        printf("NO.5 params : %s\n",argv[4]);

        return 0;
}

结果:
在这里插入图片描述

2、cp复制命令的步骤

(1)打开原文件,并读取原文件的大小;
(2)将原文件的内容读取到缓冲区;
(3)打开目标文件,若不存在则创建;
(4)将缓冲区中的内容写进目标文件;
(5)最后记得关闭两个文件;

3、实现mycp

代码:

#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;//source file缩写src,源文件的文件描述符
        int fdDes;//destination file缩写des,目标文件的文件描述符

        char *readBuf = NULL;//如果不malloc,这就成了野指针

        if(argc != 3){//cp命令:cp file1 file2只需要三个参数
                printf("参数error!\n");
                exit(-1);
        }

        fdSrc = open(argv[1],O_RDWR);

        int size = lseek(fdSrc,0,SEEK_END);//计算文件长度,字节数
        readBuf = (char *)malloc(sizeof(char)*size + 8);//+8可有可无,多加8个字节空间而已
        lseek(fdSrc,0,SEEK_SET );//光标定位到文件初始处再读

        int n_read = read(fdSrc,readBuf,size);//读取源文件至缓冲区

        fdDes = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);

        write(fdDes,readBuf,strlen(readBuf));//缓冲区数据写入目标文件
        //sizeof()计算指针长度,strlen()计算字符串长度,sizeof(buf)最多8个字节,所以这里用strlen

        close(fdSrc);
        close(fdDes);

        return 0;
}

结果:
在这里插入图片描述

二、配置文件的修改

1、简单介绍strstr函数

作用:用于判断字符串needle是否是haystack的子串;如果是,则该函数返回needle在haystack中首次出现的地址;否则返回NULL。
函数原型:

#include <string.h>
char *strstr(const char *haystack, const char *needle);

参数介绍:

haystack:将要被查找的目标字符串。
needle:将要被查找的对象字符串。

返回值:

返回值为char * 类型( 返回指向haystack中第一次出现的needle的指针);
如果needle不是haystack的一部分,则返回空指针

简单来说
定义strstr(str1,str2)

1、如果str1包含有str2: char str2 = “cdef”; char str1 = “abcdefgh”;
则通过函数,将返回 strstr(str1,str2) = cdefgh;
2、如果str1不包含有str2: char str2 = “cdef”; char str1 = “abcdefgh”;
则通过函数,将返回 strstr(str1,str2) = NULL;

如果未看懂可参考:strstr函数详解

2、实现字符修改

代码:

#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;//source file缩写src,源文件的文件描述符

        char *readBuf = NULL;//如果不malloc,这就成了野指针

        if(argc != 2){//修改1个文件,所以2个参数够了
                printf("参数error!\n");
                exit(-1);
        }

        fdSrc = open(argv[1],O_RDWR);

        int size = lseek(fdSrc, 0, SEEK_END);
        readBuf = (char *)malloc(sizeof(char)*size + 8);//+8可有可无,多加8个字节空间而已
        lseek(fdSrc,0,SEEK_SET );//光标定位到文件初始处再读

        int n_read = read(fdSrc,readBuf,size);

        char *p = strstr(readBuf,"LENG=");
        if(p==NULL){
                printf("没有找到有关字符\n");
        }

        p = p+strlen("LENG=");
        *p = '8';//字符8,不是数字

        lseek(fdSrc,0,SEEK_SET);//光标定位到文件初始处再读

        write(fdSrc,readBuf,strlen(readBuf));//sizeof()计算指针长度,strlen()计算字符串长度,sizeof(buf)最多8个字节,所以这里用strlen

        close(fdSrc);

        return 0;
}

结果:

原文件修改后
在这里插入图片描述在这里插入图片描述

三、写一个整数到文件

只需要清楚ssize_t write(int fd, const void *buf, size_t count);中间buf是无字符类型的指针,所里这里&data,取地址就可以了。
代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc,char argv[])
{
        int fd;//file description文件描述

        int date1 = 100;
        int date2 = 0;

        fd = open("./file1",O_RDWR);

        //ssize_t write(int fd, const void *buf, size_t count);写函数原型
        int n_write = write(fd,&date1,sizeof(int));//sizeof(int)

        lseek(fd,0,SEEK_SET);//光标定位

        //ssize_t read(int fd, void *buf, size_t count);读函数原型
        int n_read = read(fd,&date2,sizeof(int));

        printf("read %d \n",date2);

        close(fd);

        return 0;
}

结果:
在这里插入图片描述

四、写一个结构体数组到文件

一样,用date2[0].a结构体的访问方式就行。
代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

struct Test
{
        int a;
        char c;
};

int main(int argc,char argv[])
{
        int fd;//file description文件描述

        struct Test date1[2] = {{100,'c'},{101,'b'}};
        struct Test date2[2];

        fd = open("./file1",O_RDWR);

        //ssize_t write(int fd, const void *buf, size_t count);写函数原型
        int n_write = write(fd,&date1,sizeof(struct Test)*2);

        lseek(fd,0,SEEK_SET);//光标定位

        //ssize_t read(int fd, void *buf, size_t count);读函数原型
        int n_read = read(fd,&date2,sizeof(struct Test)*2);

        printf("read %d,%c\n",date2[0].a,date2[0].c);
        printf("read %d,%c\n",date2[1].a,date2[1].c);
        
        close(fd);

        return 0;
}

结果:
在这里插入图片描述

最后谢谢阅读,笔者乃小白,如有错误之处还请指正。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Apibro

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值