zoukankan      html  css  js  c++  java
  • C/C++(文件操作二)

    二进制读写才是本质

    二进制的读写对文件标记不敏感。
    eg: 对图片进行加密与解密:
    用命令的形式去执行:
    //xx.exe -c src dest 加密
    //xx.exe -d src dest 解密
    他的参数就是argv[0-3]------使用Qt

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    void encode(char *buf,int n) {
        for(int i = 0;i < n;i++) {
            buf[i]++;
        }
    }
    void decode(char *buf,int n) {
        for(int i = 0;i < n;i++) {
            buf[i]--;
        }
    }
    int main(int argv,char *argv[]) {
        if(argv != 4) {
            printf("use xx.exe -d[-c] src dest
    ");
            exit(-1);
        }
        FILE *pfr = fopen(argv[2],"rb+");
        if(pfr == NULL) {
            exit(-1);
        }
        FILE *pfw = fopen(argv[3],"wb+");
        if(pfw == NULL) {
            fclose(pfr);
            exit(-1);
        }
        int buf[1024];
        int n;
        if(strcmp(argv[1],"-c") == 0) {
            while((n = fread((void *)buf,1,1024,pfr)) > 0) {
                encode(buf,n);//加密函数
                fwrite((void *)buf,1,n,pfw);
            }
        }else if(strcmpy(argc[1],"-d") == 0) {
             while((n = fread((void *)buf,1,1024,pfr)) > 0) {
                encode(buf,n);//加密函数
                fwrite((void *)buf,1,n,pfw);
            }    
        }else{
            printf("arg error
    ");
        }
        fclose(pfr);
        fclose(pfw);
    
        return 0;
    }
    
    

    读写结构体的优势

    结构体中的数据类型不统一,此时最适合用二进制的方式进行读写。二进制的接口可以读文本,而文本的接口不可以读二进制。

    #include<stdio.h>
    typedef struct student{
        int num;
        char name[30];
        char sex;
        float math;
        float english;
        float chinese;
    }Stu;
    
    int main() {
        Stu s[5] = {
            {1001,"assassin",'f',89,99,100},
            {1002,"wunworld",'f',99,89,79},
            {1003,"intelwisd",'m',98,80,100},
            {1004,"seafwg",'m',99,90,99},
            {1005,"xxxx",'f',90,99,100}
        };//把初始化的内容写进结构体中,读出来。
    //把数据以二进制形式保存,文本原样保存
        FILE * pfs = fopen("stu.data","w+");
        if(pfs == NULL) {
            exit(-1);
        }
        for(int i = 0;i < 5;i++) {
            fwrite((void *)&s[i],sizeof(Stu),1,pfs);//注意&s[i],对数组取地址
        }
        fclose(pfs);
        return 0;
    }
    

    为什么结构体采用fread/fwrite来都写?

    1.结构体数据类型不统一
    2.可以将二进制转化为文本,降低效率,占用多余的存储空间。

    读文件:
    #include<stdio.h>
    typedef struct student{
        int num;
        char name[30];
        char sex;
        float math;
        float english;
        float chinese;
    }Stu;
    
    int main() {
        Stu s[5] = {
            {1001,"assassin",'f',89,99,100},
            {1002,"wunworld",'f',99,89,79},
            {1003,"intelwisd",'m',98,80,100},
            {1004,"seafwg",'m',99,90,99},
            {1005,"xxxx",'f',90,99,100}
        };//把初始化的内容写进结构体中,读出来。
    //把数据以二进制形式保存,文本原样保存
        FILE * pfw = fopen("stu.data","w+");
        if(pfw == NULL) {
            exit(-1);
        }
        Stu s;
        while(fread((void *)&s,sizeof(Stu),1,pfw)) {
            printf("num     = %d
    ",s.num);
            printf("name    = %s
    ",s.name);
            printf("sex     = %c
    ",s.sex);
            printf("math    = %.2f
    ",s.math);
            printf("english = %.2f
    ",s.english);
            printf("chinese = %.2f
    ",s.chinese);
        }
    
        fclose(pfw);
        return 0;
    }
    

    假如以小空间来读大数据的情况,在while循环中使用循环,通过循环的小标逐渐读出数据

    #include<stdio.h>
    typedef struct student{
        int num;
        char name[30];
        char sex;
        float math;
        float english;
        float chinese;
    }Stu;
    
    int main() {
        Stu s[5] = {
            {1001,"assassin",'f',89,99,100},
            {1002,"wunworld",'f',99,89,79},
            {1003,"intelwisd",'m',98,80,100},
            {1004,"seafwg",'m',99,90,99},
            {1005,"xxxx",'f',90,99,100}
        };//把初始化的内容写进结构体中,读出来。
    //把数据以二进制形式保存,文本原样保存
        FILE * pfw = fopen("stu.data","w+");
        if(pfw == NULL) {
            exit(-1);
        }
        Stu s[3];//有3个,结构体有5个
        while(fread((void *)&s,sizeof(Stu),1,pfw)) {
            for(int i = 0;i < n;i++) {
                printf("num     = %d
    ",s[i].num);
                printf("name    = %s
    ",s[i].name);
                printf("sex     = %c
    ",s[i].sex);
                printf("math    = %.2f
    ",s[i].math);
                printf("english = %.2f
    ",s[i].english);
                printf("chinese = %.2f
    ",s[i].chinese);
            }
        }
    
        fclose(pfw);
        return 0;
    }
    

    实践:将链表作为内存数据模型,见文件作为数据库,将终端作为交互界面。读文件生成链表,修改链表写入文件。

    //1.初始化数据库,此时的数据库是文件
    //2.都数据库,生成内存数据模型,链表
    //3.增,查,改,删,排序
    //4.更新数据库
    typedef struct student
    {
        char name[30];
        char sex;
        int age;
        float score;
    }Stu;
    typedef struct _StuNode
    {
        Stu data;
        struct _StuNode *next;
    }StuNode;
    
    void initData2File()
    {
        Stu s[4] =
        {
            {"assassin",'f',30,100},
            {"wunworld",'f',27,79},
            {"intelwisd",'m',25,100},
            {"seafwg",'m',23,99},
            {"xxxx",'f',23,100}
        }
        FILE *pf = fopen("stu.data","w+");
        if(NULL == pf)
            exit(-1);
        fwrite((void *)s,sizeof(s),1,pf);
        fclose(pf);
        
        return ;
    }    
    
    StuNode *createListFromFile(char *filePath)
    {
        FILE *pf = fopen(filePath,"r+");//格式写正确不然一不小心会覆盖
        if(NULL == pf)
            exit(-1);
        StuNode *head = (StuNode *)malloc(sizeof(StuNode));
        head->next = NULL;
    
        StuNode *cur = (StuNode *)malloc(sizeof(StuNode));
        while(fread((void *)&cur->data,sizeof(Stu),1,pf) )
        {
            cur->next = head->next;
            head->next = cur;
    
            cur = (StuNode *)malloc(sizeof(StuNode));
        }
        free(cur);
        return head;
    }
    void traverseStuList(StuNode *head) 
    {
        printf("name			sex		age		score
    ");
        head = head->next;
        while(head) 
        {
            printf("%-10s		%c		%d		%.2f
    ",head->data.name,head->data.sex,head->data.age,head->data.score);
            head = head->next;
        }
    }
    
    void addListStuNode(StuNode *head)
    {
        StuNode *cur = (StuNode *)malloc(sizeof(StuNode));
        printf("name:
    ");
        scanf("%s",cur->data.name);
        
        getchar();
        printf("sex:
    ");
        scanf("%c",&cur->data.sex);
        
        getchar();
        printf("age:
    ");
        scanf("%sd",&cur->data.age);
    
        getchar();
        printf("score:
    ");
        scanf("%f",c&ur->data.score);
    
        cur->next = head->next;
        head->next = cur;
    }
    
    StuNode * searchListStu(StuNode *head) 
    {
        char name[30];
        printf("pls input your search name:");
        scanf("%d",name);
        head = head->next;
        while(head)
        {
            if(strcmp(head-data.name,name) == 0)
                break;
            head - head->next;
        }
        return head;
    }
    //删除操作
    void deleteListNodeStu(StuNode *head)
    {
        StuNode *pfind = searchListStu(head);
        if(pfind == null)
        {
            printf("你所要删除的人不存在!
    ");
            return ;
        }
        while(head->next != pfind)
        {
            head = head->next;//找到前驱
        }
        head->next = pfind->next;
        free(pfind);
        return ;
    }
    //
    int lenListStu(StuNode *head)
    {
        int len;
        head = head->next;
        while(head)
        {
            len++;
            head = head->next;
        }
        return len;
    }
    void sortListStu(StuNode *head)
    {
        int len = lenListStu(head);
        StuNode *prep,*p,*q;
        for(int i = 0;i < len-1;i++)
        {
            prep = head;
            p = prep->next;
            q = q->next;
            for(int j = 0;j < len-1-i;j++)
            {
            if(strcmp(p->data.name,q->data.name) > 0) 
            {
                prep->next = q;
                p->next = q->next;
                q->next = p;
    
                prep = q;
                q = p->next;
                continue;
            }
            prep = prep->next;
            p = p->next;
            q = q->next;
            }
        }
    }
    void saveList2FileStu(StuNode *head,char *filePath)
    {
        FILE *pf = fopen(filePath,"w+");
        if(NULL == pf)
            exit(-1);
        head = head->next;
        while(head)
        {
            fwrite((void *)&head->data,sizeof(Stu),1,pf);
            head =head->next;
        }
        fclose(pf);
    }
    void destoryListStu(head)
    {
        StuNode *t;//找个替身
        while(head)
        {
            t = head;
            head = head->next;
            free(t);
        }
    }
    int main() 
    {
        //initdata2File();
        StuNode *head = createListFromFile("stu.data");
        /*
        traverseStuList(head);
        printf("1->add	 2->search	 3->delete	4->exit
    ");
        int choice;
        scanf("%d",&choice);
        switch(choice)
        {
            case 1:
                addListStuNode(head);
                break;
            case 2:
                break;
            case 3:
                break;
            case 4:
                break;
            default:
                printf("你输入错误!
    ");
        }*/
    
        StuNode *pfind;
        while(1)
        {
            system("cls");//系统清屏
            traverseStuList(head);
            printf("1->add	 2->search	 3->delete	4->exit
    ");
            int choice;
            scanf("%d",&choice);
            switch(choice)
            {
                case 1:
                    addListStuNode(head);
                    break;
                case 2:
                    if(pfind = searchListStu(head)) 
                    {
                        printf("%-10s		%c		%d		%.2f
    ",pfind->data.name,pfind->data.sex,pfind->data.age,pfind->data.score);
            
                    }
                    else
                    {
                        printf("没有此人!
    ");
                    }
                    break;
                case 3:
                    deleteListNodeStu(head);
                    break;
                case 4:
                    sortListStu(head);
                    break;
                case 5:
                    saveList2FileStu(head,"stu.data");
                    destoryListStu(head);
                    return 0;
                default:
                    printf("你输入错误!
    ");
            }    
        }
    }
    

    文件偏移

    int main() 
    {
        FILE *pf = fopen("xxx.txt","w=");
        fputs("abcdefg",pf);
        int n = ftell(pf);//
        printf("n = %d
    ",n);//n = 7,ftell(),求字节的大小
        rewind(pf);//将文件重新指针向一个流的开头
        n = ftell(pf);
        printf("n = %d
    ",n);//0
    
        feek(pf,0,SEEK_END);//操作文件pf,从SEEK_END末尾偏移0个单位。
        n = ftell(pf);
        printf("n = %d
    ",n);//7
    
        feek(pf,0,SEEK_SET);//从头偏移0个
        n = ftell(pf);
        printf("n = %d
    ",n);//0
    
        feek(pf,1,SEEK_CUR);//从当前位置偏移一个单位
        n = ftell(pf);
        printf("n = %d
    ",n);//0
        
    
        return 0;
    }
    
  • 相关阅读:
    mock.js 模拟数据
    pa
    观察者模式
    WebSocket
    Nginx官方文档学习
    Java中文乱码解决
    Jersey+Spring+Maven(转)
    App架构经验总结(转)
    JSONP跨域的原理解析(转)
    mongoDB学习
  • 原文地址:https://www.cnblogs.com/intelwisd/p/8419953.html
Copyright © 2011-2022 走看看