c语言操作文件(待补充)

内容概要

  一、打开和关闭文件

  二、打开文件的几种模式

  三、文本模式:fputc,fgetc,fputs,fgets,fscanf,fprintf

  四、二进制模式:fwrite,fread

  五、文件操作小练习

 

1、打开和关闭文件

  fopen(字符串参数一,字符串参数二);

    功能:打开文件

    参数:参数一,文件名,可以是相对路径,也可以是绝对路径,默认为当前路径

       参数二,打开文件的模式(注意这里必须是字符串而不是字符)

    返回值:文件指针或NULL

 

  fclose(文件指针)

    功能:关闭文件

    返回值:整形(应该用于表示函数是否执行成功)

 

  使用typedef类型FILE *定义文件指针

#include <stdio.h>
#include <stdlib.h>

int main(void){
    
    FILE *pfp;
    pfp = fopen("hello.txt", "w");
    
    if (pfp == NULL){
        printf("open file error!\n"); //文件打开失败时返回NULL
        exit(EXIT_FAILURE);
    }
    
    fclose(pfp);
    pfp = NULL;  //pfp依旧存有文件的地址,但是那个空间已经被释放了
    return 0;
}

  注意:和python的open()函数一样,fopen()只是向操作系统发送打开文件的请求,如果不使用fclose,那么这部分资源不会被操作系统释放,即使你关闭了可执行程序

 

2、打开文件的几种模式

  c语言文件打开的模式与python是一样的

r 以只读方式打开文件,该文件必须存在。
r+ 以读/写方式打开文件,该文件必须存在。
rb+ 以读/写方式打开一个二进制文件,只允许读/写数据。
rt+ 以读/写方式打开一个文本文件,允许读和写。
w 打开只写文件,若文件存在则长度清为0,即该文件内容消失,若不存在则创建该文件。
w+ 打开可读/写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留(EOF符保留)。
a+ 以附加方式打开可读/写的文件。若文件不存在,则会建立该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(原来的EOF符 不保留)。
wb 以只写方式打开或新建一个二进制文件,只允许写数据。
wb+ 以读/写方式打开或建立一个二进制文件,允许读和写。
wt+ 以读/写方式打开或建立一个文本文件,允许读写。
at+ 以读/写方式打开一个文本文件,允许读或在文本末追加数据。
ab+ 以读/写方式打开一个二进制文件,允许读或在文件末追加数据。

  默认情况下为t文本模式

    "w" => "wt"

 

  二进制和文本模式的区别:

    在windows系统中,文本模式下,文件以"\r\n"代表换行。若以文本模式打开文件,并用fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"\r\n" 。

    在类Unix/Linux系统中文本模式下,文件以"\n"代表换行。所以Linux系统中在文本模式和二进制模式下并无区别。

    在mac操作系统下,文本模式以\r表示换行,fputs等函数写入换行符"\n"时,会被替换为\r。

 

    c语言在文件末尾处会添加一个结束符EOF(-1)表示文件已经读取完毕

 

3、文本模式

  fputc(整形表示字符常量的ascii编码值,文件指针)

    //  file put char的意思

    功能:往文件中添加一个字符

    返回值:整形

 

  fgetc(文件指针)

    //  flie get char的意思

    功能:从文件中拿取一个字符

    返回值:字符常量的ascii编码值

#include <stdio.h>
#include <stdlib.h>

int main(void){
    
    FILE *file;
    int ch;
    
    file = fopen("hello.txt", "r");
    if (file == NULL){
        printf("open file error!\n");
        exit(EXIT_FAILURE);
    }
    
    /*while ((ch = fgetc(file)) != EOF){
        printf("%c", ch);
    }*/
    
    do {
        ch = fgetc(file);
        if (ch == EOF){
            printf("%d", ch);
        }
    }
    while (ch != EOF);
    
    putchar('\n');
    
    fclose(file);
    file = NULL;
    return 0;
}

 

  fputs(字符指针或数组,文件指针)

    //  file put string的意思

    功能:往文件中写入一个字符串,字符串自动添加的\0会被忽略

    返回值:整形

 

    检验fputs会将字符串自动添加的\0去掉

      这段代码在windows下dev-c++下是能找到\0的;在虚拟机上就进入死循环了

#include <stdio.h>
#include <stdlib.h>

int main(void){
    
    FILE *fp;
    int c;
    
    if ((fp = fopen("hello.txt", "w")) == NULL){
        printf("open the file error!\n");
        exit(EXIT_FAILURE);
    }
    
    fputs("hello world", fp);
    
    while (1){
        c = fgetc(fp);
        if (c == '\0'){
            printf("find the char \\0\n");
            break;
        }
    }
    
    return 0;
}

 

  fgets(字符指针或者数组,读取字符的数量size,文件指针)

    //  file get string的意思

    功能:往文件种读取一个字符串

    参数:参数一,参数一用于存放得到字符串

       参数二,参数二用于限制读取到的字符数量,注意读取到的字符串会自动加上\0,所以实际得到的字符数量为(size-1),同时size-1表示读取的最大字符数量,如果在读取过程中遇到\n,则结束读取

 

 

  fprintf(文件指针,写入文件的字符串格式,传入占位符的实际数据)

    功能:类似printf将数据格式化输出到终端,fprintf是将数据输出到文件上

 

  fscanf(文件指针,按怎样的格式将文件中的数据读取到内存,用于存储相应值得变量地址1,地址2...)

    功能:格式化将文件内容读取到并保存到变量中

 

    time.h库

#include <stdio.h>
#include <time.h>

int main(void){
    
    struct tm *time1; //这里必须是指针,不是结构体变量
    time_t t;
    time(&t); //这是时间戳
    
    printf("t:%lld\n", t);
    time1 = localtime(&t); //将时间戳解析
    
    printf("tm_sec:%d\n", time1.tm_sec); // 秒,从0到59
    printf("tm_min:%d\n", time1.tm_min); // 分,从0到59
    printf("tm_hour:%d\n", time1.tm_hour); // 小时,从0到23
    printf("tm_mday:%d\n", time1.tm_mday); // 一个月的第几天,从1到31
    printf("tm_mon:%d\n", time1.tm_mon); // 月,从0到11
    printf("tm_year:%d\n", time1.tm_year); // 自1900年起的年数
    printf("tm_wday:%d\n", time1.tm_wday); // 一周中的第几天,范围从0到6
    printf("tm_yday:%d\n", time1.tm_yday); // 一年中的第几天,范围从0到365
    printf("tm_isdst:%d\n", time1.tm_isdst); // 夏令时
    
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void){
    
    struct tm *ptm;
    time_t t;
    time(&t);
    
    ptm = localtime(&t);
    
    FILE *fp;
    
    if ((fp = fopen("hello.txt", "w")) == NULL){
        printf("open the file error!\n");
        exit(EXIT_FAILURE);
    }
    
    fprintf(fp, "%d-%d-%d", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday);
    
    fclose(fp);
    
    if ((fp = fopen("hello.txt", "r")) == NULL){
        printf("open the file error!\n");
        exit(EXIT_FAILURE);
    }
    
    int year, month, day;
    fscanf(fp, "%d-%d-%d", &year, &month, &day);
    
    fclose(fp);
    fp = NULL;
    
    printf("year:%d, month:%d, day:%d\n", year, month, day);
    
    return 0;
}

 

4、二进制模式:fread,fwrite

  文本模式下的文件中的数据本质还是二进制方式存储的,只是中间做了一层转换,变成人能识别的字符(英语符号,汉语,日语,法语等)

    这个转换关系就是字符编码

 

  fread(用于指向存储位置的任意类型的指针, 每个元素的大小,元素个数,文件指针)

    功能:读取二进制数据

    返回值:无符号long long(表示读取成功的元素数量)

 

  fwrite(任意类型的指针, 每个元素的大小,元素个数,文件指针)

    功能:类似python中json模块和pickle模块,可以实现将非字符(结构体等)以二进制形式存储到文件中

    返回值:无符号long long(表示写入成功的元素数量)

 

    以二进制模式写入文件,以文本模式读取内容

#include <stdio.h>
#include <stdlib.h>

int main(void){
    
    FILE *file;
    int a = 67, *pa = &a;
    int ch;
    
    file = fopen("hello.txt", "wb");
    if (file == NULL){
        printf("open file error!\n");
        exit(EXIT_FAILURE);
    }
    
    fwrite(pa, 4, 1, file);
    
    fclose(file);
    file = NULL;
    
    file = fopen("hello.txt", "a");
    if (file == NULL){
        printf("open file error!\n");
        exit(EXIT_FAILURE);
    }
    
    ch = fgetc(file);
    printf("%c\n", ch); //这里打印了大写的C,因为67就是大写字母C的asciii编码值
    
    fclose(file);
    file = NULL;
    return 0;
}

  二进制模式存放/读取结构体变量

    结构体存放

#include <stdio.h>
#include <stdlib.h>

struct Book{
    char name[32];
    char author[32];
    float price;
};

typedef struct Book To_book, *P_to_book;

int main(void){
    
    FILE *file;
    P_to_book pbook1;
    int num;
    
    To_book book1 = {
        "hahahaha",
        "emmmmmmm",
        52.2,
    };
    
    pbook1 = &book1;
    
    file = fopen("hello.txt", "rb");
    if (file == NULL){
        printf("open file error!\n");
        exit(EXIT_FAILURE);
    }
    
    num = fwrite(pbook1, sizeof(To_book), 1, file);
    printf("%llu\n", num);
    
    fclose(file);
    file = NULL;
    
    return 0;
}

    结构体读取

#include <stdio.h>
#include <stdlib.h>

struct Book{
    char name[32];
    char author[32];
    float price;
};

typedef struct Book To_book, *P_to_book;

int main(void){
    
    FILE *file;
    P_to_book pbook1;
    int num;
    
    file = fopen("hello.txt", "rb");
    if (file == NULL){
        printf("open file error!\n");
        exit(EXIT_FAILURE);
    }
    
    num = fread(pbook1, sizeof(To_book), 1, file);
    printf("num : %llu\n", num);
    
    fclose(file);
    file = NULL;
    
    return 0;
}

    存放数组

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
    
    FILE *file;
    char str[20] = "hello world";
    char *pstr;
    int length = strlen(str);
    int num;
    
    pstr = str;
    
    file = fopen("hello.txt", "wb");
    if (file == NULL){
        printf("open file error!\n");
        exit(EXIT_FAILURE);
    }
    
    num = fwrite(pstr, length, 1, file);
    printf("num : %u\n", num);
    
    fclose(file);
    file = NULL;
    
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
    
    FILE *file;
    char str[20] = "hello world";
    char *pstr;
    int num;
    
    pstr = str;
    
    file = fopen("hello.txt", "wb");
    if (file == NULL){
        printf("open file error!\n");
        exit(EXIT_FAILURE);
    }
    
    num = fwrite(pstr, sizeof(str), 1, file);
    printf("num : %u\n", num);
    
    fclose(file);
    file = NULL;
    
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
    
    FILE *file;
    char str[20] = "hello world";
    int num;
    
    file = fopen("hello1.txt", "wb");
    if (file == NULL){
        printf("open file error!\n");
        exit(EXIT_FAILURE);
    }
    
    num = fwrite(str, sizeof(str), 1, file);
    printf("num : %u\n", num);
    
    fclose(file);
    file = NULL;
    
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
    
    FILE *file;
    char str[20] = "hello world";
    char *pstr;
    int num;
    
    pstr = str;
    
    file = fopen("hello1.txt", "wb");
    if (file == NULL){
        printf("open file error!\n");
        exit(EXIT_FAILURE);
    }
    
    num = fwrite(pstr, 1, 11, file);
    printf("num : %u\n", num);
    
    fclose(file);
    file = NULL;
    
    return 0;
}

    说白了,c语言其实没有对语法那么严格,终究遵照 内存地址+数据长度+解析方式

    尝试对其它类型的数组(指针数组,整形数组和结构体数组)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 5

struct Book{
    char name[20];
    char author[20];
    float price;
};

typedef struct Book To_book;

int main(void){
    
    FILE *file;
    To_book library[N];
    
    if ((file = fopen("hello.txt", "wb")) == NULL){
        printf("open file error!n");
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < N; i++){
        printf("please input information about the book(for example helloworld haha 52.1):\n");
        scanf("%s %s %f", library[i].name, library[i].author, &library[i].price);
    }
    
    fwrite(library, sizeof(To_book), N, file);
    
    fclose(file);
    file = NULL;
    
    if ((file = fopen("hello.txt", "ab")) == NULL){
        printf("open file error!|n");
        exit(EXIT_FAILURE);
    }
    
    int *array[N];
    int a;
    
    for (int i = 0; i < N; i++){
        array[i] = &a;
    }
    
    fwrite(array, sizeof(int *), N, file);
    
    fclose(file);
    file = NULL;
    return 0;
}

 

5、文件操作小练习

  一个创建文件并且传入字符串的小功能

#include <stdio.h>

void un_user_char(void);
void put_str(FILE *);

void un_user_char(void){
    while (getchar() != '\n'){
        ;
    }
}

void put_str(FILE *file){
    char str[1024];
    printf("please input a string:");
    scanf("%s", str);
    fputs(str, file);
}

int main(void){
    char choice;
    char filename[20];
    FILE *file;
    
    printf("please input filename:");
    scanf("%s", filename);
    un_user_char();
    
    file = fopen(filename, "w");
    if (file == NULL){
        printf("open file error!\n");
    }
    
    while (1){
        printf("please input if you want to add string(y/n):");
        scanf("%c", &choice);
        un_user_char();
        
        if ('y' == choice){
            put_str(file);
            un_user_char();
        }
        else if ('n' == choice){
            break;
        }
        else {
            printf("please input a qualified cammond!\n");
        }
    }
    
    fclose(file);
    file = NULL;
    
    return 0;
}

  -实现一个复制的小功能

  **main(int argc, char *argv[])解析**

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ONE_GET_MAX 1024

int main(int argc, char *argv[]){
    FILE *file = NULL, *file_cpy = NULL;
    
    if ((file = fopen(argv[1], "rb")) == NULL){
        printf("open file error!\n");
        exit(EXIT_FAILURE);
    }
    
    if ((file_cpy = fopen(argv[2], "wb")) == NULL){
        printf("create file error!\n");
        exit(EXIT_FAILURE);
    }
    
    char *pstr = (char *)malloc(sizeof(1024));
    
    while (!feof(file)){
        fread(pstr, ONE_GET_MAX ,1 ,file);
        fwrite(pstr, strlen(pstr), 1, file_cpy);
    }
    
    fclose(file);
    fclose(file_cpy);
    file = NULL;
    file_cpy = NULL;
    return 0;
}

  最后一个练习

    结合之前内容,完成一个添加书籍的功能

 

***待补充***

posted @ 2021-03-27 13:09  口乞厂几  阅读(183)  评论(0)    收藏  举报