美文网首页
C语言文件

C语言文件

作者: AuglyXu | 来源:发表于2018-09-14 16:49 被阅读0次

    文件的打开和关闭

    fopen / fclose函数
    • fopen第一个参数接收打开的文件的名称的字符串,第二个参数接收的是打开文件的方式

      • 打开文件的方式:
        1. r 只读文件 文件不存在时报错

        2. w 只写文件 文件不存在时新建 文件存在时覆盖

        3. a 追加文件(只写) 文件不存在时新建 文件存在时在原有文件后追加

        4. r+ 读写文件 文件不存在时报错 存在时打开

        5. w+ 读写文件 文件不存在时新建 文件存在时覆盖

        6. a+ 追加文件(读写) 文件不存在时新建 文件存在时在原有文件后追加

      • 返回值:指向文件缓冲区的指针,该指针操作文件的句柄
    • fclose接收一个参数

      • 参数是指向文件缓冲的指针

      • 返回值:int 成功返回 0 ,失败返回 EOF(-1)。


    文件的读写(文本文件操作)

    一次性写一个字符(fputc)
    • int fputc (int ch, FILE * stream );//函数声明

    • 接收两个参数

      1.第一个参数是写入的字符

      2.第二个参数是指向文件缓冲的指针

    • 返回值:int 写入成功,返回写入成功字符,如果失败,返回 EOF。

    • 注意点:

      1.不会在写入数据的后面添加\n

      2.写入的时候遇到\0就会自动停止写入

    代码如下:

        // 1.打开一个文件
        FILE *fp = fopen("test.txt", "w+");
        // 2.往文件中写入内容
        for(char ch = 'a'; ch <= 'z'; ch++){
            // 一次写入一个字符
            char res = fputc(ch, fp);
            printf("res = %c\n", res);
        }
        // 3.关闭打开的文件
        fclose(fp);
    
    一次性读一个字符(fgetc)
    • int fgetc ( FILE * stream );//声明

    • 参数:文件缓冲的指针

    • 注意点:返回文件缓冲指针指向地址的那个字节,写入文件后文件缓冲的指针需要归位

    • 返回值:int 正常,返回读取的字符;读到文件尾或出错时,为 EOF。

        // 1.打开一个文件
        FILE *fp = fopen("test.txt", "r+");
        // 2.从文件中读取内容
        char res = EOF;
        while((res = fgetc(fp)) != EOF){
            printf("res = %c\n", res);
        }
        // 3.关闭打开的文件
        fclose(fp);
    
    一次性写一行字符(fputs)
    • int fputs(char *str,FILE *fp)

    • 第一个参数: 表示指向的字符串的指针。

    • 第二个参数: 表示指向文件流结构的指针

    • 返回值:int 正常,返 0;出错返 EOF。

    {
        FILE *fw = fopen("test.txt", "w+");
        // 注意: fputs不会自动添加\n
        fputs("lnj\n", fw);
        fputs("it666\n", fw);
        fclose(fw);
        return 0;
    }
    
    • 一次性读一行字符(fgets)

      • char *fgets(char *str,int length,FILE *fp)

      • 第一个参数: 指向需要读入数据的缓冲区。

      • 第二个参数: 每一次读数字符的字数。

      • 第三个参数: 指向文件流结构的指针

      • 返回值:char * 正常,返 str 指针;出错或遇到文件结尾 返空指针 NULL。

    • 注意点:
      1.最多只能读取N-1个字符,最后自己添加\0

      2.读取到\n或者EOF自动结束


    文件的读写(二进制文件操作)

    一次性写入一块数据(fwrite)
    • int fwrite(void *buffer, int num_bytes, int count, FILE *fp)

    • 第一个参数:指向要写入数据存储区的首地址的指针

    • 第二个参数:一次读取的字节数

    • 第三个参数:读取的次数

    • 第四个参数:文件流结构的指针

    • 返回值:int 成功,返回写的字段数;出错或文件结束,返回 0

        FILE *fp = fopen("test.txt", "wb+");
        // 注意: fwrite不会关心写入数据的格式
        char *str = "lnj\0it666";
         /*
         * 第一个参数: 被写入数据指针
         * 第二个参数: 每次写入多少个字节
         * 第三个参数: 需要写入多少次
         * 第四个参数: 已打开文件结构体指针
         */
        fwrite((void *)str, 9, 1, fp);
        fclose(fp);
    
    一次读取一块数据
    • int fread(void *buffer, int num_bytes, int count, FILE *fp)

    • 第一个参数:读取后存放的地址

    • 第二个参数:一次读取的字节数

    • 第三个参数:读取的次数

    • 第四个参数:已打开文件结构体指针

    • 返回值: int 成功,返回读的字段数;出错或文件结束,返回 0。

    • 注意点:

      1.读取时num_bytes应该填写读取数据类型的最小单位, 而count可以随意写

      2.如果读取时num_bytes不是读取数据类型最小单位, 会引发读取失败


    读写结构体

    • 读写结构体数组
    #include <stdio.h>
    
    typedef struct{
        char name[5];
        int age;
        double height;
    } Person;
    
    int main()
    {
        Person ps[] = {
          {"zs", 18, 1.65},
          {"ls", 21, 1.88},
          {"ww", 33, 1.9}
        };
    
    
        FILE *fp = fopen("person.stu", "wb+");
        fwrite(&ps, sizeof(ps), 1, fp);
    
        rewind(fp);
        Person p;
        while(fread(&p, sizeof(p), 1, fp) > 0){
            printf("name = %s\n", p.name);
            printf("age = %i\n", p.age);
            printf("height = %lf\n", p.height);
        }
        return 0;
    }
    
    • 读写结构体链表
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct person{
        char name[5];
        int age;
        double height;
        struct person* next;
    } Person;
    Person *createEmpty();
    void  insertNode(Person *head, char *name, int age, double height);
    void printfList(Person *head);
    int saveList(Person *head, char *name);
    Person *loadList(char *name);
    
    int main()
    {
    
    //    Person *head = createEmpty();
    //    insertNode(head, "zs", 18, 1.9);
    //    insertNode(head, "ls", 22, 1.65);
    //    insertNode(head, "ws", 31, 1.78);
    //    printfList(head);
    //    saveList(head, "person.list");
        Person *head = loadList("person.list");
        printfList(head);
        return 0;
    }
    
    /**
     * @brief loadList 从文件加载链表
     * @param name 文件名称
     * @return  加载好的链表头指针
     */
    Person *loadList(char *name){
        // 1.打开文件
        FILE *fp = fopen(name, "rb+");
        if(fp == NULL){
            return NULL;
        }
        // 2.创建一个空链表
        Person *head = createEmpty();
        // 3.创建一个节点
        Person *node = (Person *)malloc(sizeof(Person));
        while(fread(node, sizeof(Person), 1, fp) > 0){
            // 3.进行插入
            // 3.1让新节点的下一个节点 等于 头节点的下一个节点
            node->next = head->next;
            // 3.2让头结点的下一个节点 等于 新节点
            head->next = node;
    
            // 给下一个节点申请空间
            node = (Person *)malloc(sizeof(Person));
        }
        // 释放多余的节点空间
        free(node);
        fclose(fp);
        return head;
    }
    
    /**
     * @brief saveList 存储链表到文件
     * @param head 链表头指针
     * @param name 存储的文件名称
     * @return  是否存储成功 -1失败 0成功
     */
    int saveList(Person *head, char *name){
        // 1.打开文件
        FILE *fp = fopen(name, "wb+");
        if(fp == NULL){
            return -1;
        }
        // 2.取出头节点的下一个节点
        Person *cur = head->next;
        // 3.将所有有效节点保存到文件中
        while(cur != NULL){
            fwrite(cur, sizeof(Person), 1, fp);
            cur = cur->next;
        }
        fclose(fp);
        return 0;
    }
    /**
     * @brief printfList 遍历链表
     * @param head 链表的头指针
     */
    void printfList(Person *head){
        // 1.取出头节点的下一个节点
        Person *cur = head->next;
        // 2.判断是否为NULL, 如果不为NULL就开始遍历
        while(cur != NULL){
            // 2.1取出当前节点的数据, 打印
            printf("name = %s\n", cur->name);
            printf("age = %i\n", cur->age);
            printf("height = %lf\n", cur->height);
            printf("next = %x\n", cur->next);
            printf("-----------\n");
            // 2.2让当前节点往后移动
            cur = cur->next;
        }
    }
    
    /**
     * @brief insertNode 插入新的节点
     * @param head 链表的头指针
     * @param p 需要插入的结构体
     */
    void  insertNode(Person *head, char *name, int age, double height){
        // 1.创建一个新的节点
        Person *node = (Person *)malloc(sizeof(Person));
        // 2.将数据保存到新节点中
        node->name = name;
        node->age = age;
        node->height = height;
    
        // 3.进行插入
        // 3.1让新节点的下一个节点 等于 头节点的下一个节点
        node->next = head->next;
        // 3.2让头结点的下一个节点 等于 新节点
        head->next = node;
    }
    /**
     * @brief createEmpty 创建一个空链表
     * @return 链表头指针, 创建失败返回NULL
     */
    Person *createEmpty(){
        // 1.定义头指针
        Person *head = NULL;
        // 2.创建一个空节点, 并且赋值给头指针
        head = (Person *)malloc(sizeof(Person));
        if(head == NULL){
            return head;
        }
        head->next = NULL;
        // 3.返回头指针
        return head;
    }
    作者:极客江南
    链接:https://www.jianshu.com/p/eb12558ae490
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
    

    相关文章

      网友评论

          本文标题:C语言文件

          本文链接:https://www.haomeiwen.com/subject/tteogftx.html