Linux 文件编程(第二阶段文件操作函数的一下使用)

8.文件操作小应用之实现cp指令

需要实现cp指令要怎么做呢?(可以看看下图)思路入下图:
在这里插入图片描述
按照上面的步骤完成代码(demo13.c):

#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)//char **argv是二级指针
{
        int fdSrc;
        int fdDes;
        char *readBuf = NULL;

        if (argc != 3){
                printf("paramer 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);//用malooc开辟一个与源文件相近大小的空间,不浪费。
        int n_read = read(fdSrc,readBuf,size);//读源文件的内容

        fdDes = open(argv[2],O_RDWR|O_CREAT,0600);//打开或者创建一个文件
        int n_write = write(fdDes,readBuf,strlen(readBuf));//把读到的内容到目标文件中去。

        close(fdSrc);关闭文件,使得对动态文件的操作保存在静态文件中
        close(fdDes);

        return 0;

}

下图就是运行自己写的cp指令运行成功图:
在这里插入图片描述

9.解决上节课中的隐藏bug

#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("paramer 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);


        fdDes = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);//上节课存在的小bug是当目标文件文件存在且其大小超过源文件的大小,那么对目标文件的写操作只能覆盖源文件大小的部分,目标文件的多出部分还是会留下,所以用O_TRUNC把目标文件原来的内容全部干掉。

        int n_write = write(fdDes,readBuf,strlen(readBuf));

        close(fdSrc);
        close(fdDes);

        return 0;

}

10.文件编程小应用之修改程序的配置文件

在这里插入图片描述
就是修改文件的字符:思路如图
在这里插入图片描述
(demo14.c代码)

#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("paramer 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);
		lseek(fdSrc,0,SEEK_SET);//*注意*这里不加光标的话,write函数就是在文件的尾位置写了,所以加lseek函数使得光标返回原来位置,或者在open函数哪里加O_TRUNC常数。
	
	//此处修改字符的字段可以封装成一个函数,供以后工作参考。
        char *p = strstr(readBuf,"LENG=");//用字符串函数找出a的位置
        if(p==NULL){
                printf("not found\n");
                exit(-1);
        }
        p = p+strlen("LENG=");//然后移到b的位置
        *p = '5';//修改字符
        
        int n_write = write(fdSrc,readBuf,strlen(readBuf));

        close(fdSrc)return 0;
 } 

这里需要提醒的是在工作中需要对函数的返回值进行判断,这里就为了代码简洁没有判断read open这些函数的返回值。
下图是函数运行的图:(LENG=3成功改成LENG=5)
在这里插入图片描述

11.写一个整数到文件

前面我们都是对文件字符的读写,包括对TEST.config写的也是字符,这里我们硬是要写一个整数。
在demo15.c中把字符‘5’改为整数5如下图:
在这里插入图片描述
对TEST.config的修改如图:(不是错,只是和字符串有冲突)
在这里插入图片描述
代码(demo16.c):

#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));//write函数的第二个参数只要是地址就好了,所以可以取整形数的地址

        lseek(fd,0,SEEK_SET);
        int n_read = read(fd,&data2,n_write);//read函数的第二个参数只要是地址就好了,所以可以取整形数的地址

        printf("read %d,data=%d\n",n_read,data2);
        close(fd);

        return 0;

}

下面是运行结果file1的截图:这个结果并不是错误的,程序可以正常的读写,这个修改file1是正确的。
在这里插入图片描述
这里是把结构体写入配置文件中(demo17.c):

#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,data=%d,char=%c\n",n_read,data2.a,data2.c);
        close(fd);

        return 0;

}

下图是运行结果图,配置文件就不看了,都是乱码,程序看的懂,人看不懂!!!
在这里插入图片描述

12.写结构体数组到文件

直接上代码(demo18.c)

#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);

        lseek(fd,0,SEEK_SET);
        int n_read = read(fd,&data2,sizeof(struct Test)*2);//这里需要注意的是如果读取链表的话不能一次性读,结构体是一个块,可以一次性读,链表需要遍历链表,一次一个的读取出来。

        printf("read %d,data1=%d,char1=%c,data2=%d,char2=%c\n",n_read,data2[0].a,data2[0].c,data2[1].a,data2[1].c);
        close(fd);

        return 0;

}

下图是运行结果:(file1还是看不懂,不截图了)
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值