zoukankan      html  css  js  c++  java
  • C语言文件操作

         学习一门语言,学会文件操作是十分必要的,如果没有学会文件操作,从某种角度上来说,就基本很难体现出这种语言的价值。C语言库函数为文件操作提供了丰富的库函数,接下来我们需要做的是学会使用这些库函数,在我看来学会这些库函数已经学会文件操作的一大半了,接下来我会根据自己的理解来解析一些常用的文件操作函数。

    fopen函数

    FILE *fopen(const char *path,const char *mode)//文件指针名=fopen(文件名,使用文件方式)

         功能:打开一个文件,打开成功返回有效的文件地址,失败则返回NULL。

         path表示文件路径

         mode选择文件的打开方式:

        r      以只读的方式打开文件

        r+    以可读写方式打开文件,该文件必须存在

        rb+  读写打开一个二进制文件,允许读写数据,该文件必须存在

        rw+ 打开一个文本文件,允许读和写

        w    打开只写文件,若文件存在则长度清为0,即文件内容会消失。若文件不存在则创建该文件。

        w+  打开可读写文件,若文件存在则文件长度清为0,即该文件内容会消失。文件不存在则创建该文件。

    FILE *p =fopen(“E://1.txt”,”r”);
    if(p){
    printf(“success\n”);
    }

         只要fopen成功打开文件,使用完后一定要调用fclose关闭。fclose的参数就是fopen的返回值。

         int fclose(FILE *p);

    getc函数

         int getc(FILE *stream);

        getc的参数是fopen成功打开文件后返回的指针,getc的返回值是一个char,功能是以字节为单位读取文件内容。

        文本文件最后的结束标识符是-1,也就是宏EOF,EOF不是文件的一部分内容,只是文件结束的标识。二进制文件的结束标识符则不一定是-1。

    putc函数

         int putc(char c,FILE *stream);

         c是需要写入文件的字符,stream是fopen成功打开文件后返回的指针,功能是向文件写入一个指定的字符。

         getc必须用r模式打开,putc必须用w模式打开,读和写一定要分清模式。

         下面例子会展示通过getc和putc读写指定文件

    //使用putc例程
    int main(int argc, char **args){
        FILE *p = fopen(args[1], "w+");
        if (argc<2) return 0;
        if(p){             //指定写文件
            while(1)
            {
                char c = getchar();
                if (c == '\n')
                    break;
                putc(c, p);
            }
            fclose(p);
        }
        return 0;
    }
    //使用getc例程
    int main(int argc, char **args){
        FILE *p = fopen(args[1], "r");
        if (argc<2) return 0;
        if (p){             //指定读文件
            char c = getc(p);
            while(c != EOF){
                printf("%c", c);
                c = getc(p);
            }
            getchar();
            fclose(p);
        }
        return 0;
    }

    fgets函数与fputs函数

    int fputs(const char *str, FILE *stream);

          返回值:该函数返回一个非负值,如果发生错误则返回 EOF(-1)。str:这是一个数组,包含了要写入的以空字符终止的字符序列。stream:指向 FILE 对象的指针,该 FILE 对象标识了要被写入字符串的流

    char *fgets(char *buf, int bufsize, FILE *stream);
          *buf: 字符型指针,指向用来存储所得数据的地址。
          bufsize: 整型数据,指明存储数据的大小。
          *stream: 文件结构体指针,将要读取的文件流

           fgets从stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),如果文件中的该行,不足bufsize-1个字符,则读完该行就结束。如若该行(包括最后一个换行符)的字符数超过bufsize-1,则fgets只返回一个不完整的行,但是,缓冲区总是以NULL字符结尾,对fgets的下一次调用会继续读该行。函数成功将返回buf,失败或读到文件结尾返回NULL。

           fputs向指定的文件写入一个字符串(不自动写入字符串结束标记符‘\0’)。成功写入一个字符串后,文件的位置指针会自动后移,函数返回值为非负整数;否则返回EOF(符号常量,其值为-1)。

    int main(){
        FILE *p = fopen("x.txt", "w");
        FILE *p1 = fopen("1.txt", "r");
        if (p){
        while (!feof(p1)){  //只要没到文件结尾那么循环继续
                char buf[1024] = { 0 };
                fgets(buf, sizeof(buf), p1);
                //fgets(buf, sizeof(buf), stdin);
                if (!strncmp(buf, "exit", 4))//若str1与str2的前n个字符相同,则返回0;若s1大于s2,则返回大于0的值;若s1 小于s2,则返回小于0的值。
                    break;
                fputs(buf, p);
            }
            fclose(p);
            fclose(p1);
        }
        return 0;
    }

     EOF与feof函数文件结尾

    int feof(FILE *stream);

          如果已经是文件结尾,feof函数返回true;EOF不属于文件内容,知识文件的结尾标识,而且也不要用-1直接代替EOF。只有文本文件才能通过EOF判断文件的结尾标识,对二进制文件EOF是无效的

    fgets与fputs实现文件加密解密

    #include<stdlib.h>
    #include<string.h>
    #include<stdio.h>
    FILE *f_mp4, *P1;
    void decode(char* s)
    {
        int len = 0;
        while (s[len])
        {
            s[len]++;
            len++;
        }
    }
    void encode(char* s)
    {
        int len = 0;
        while (s[len])
        {
            s[len]--;
            len--;
        }
    }
    int main(int argc, char **args)  //通过命令行指定拷贝文件
    {
        if (argc<4) return -1;
        f_mp4 = fopen(args[1], "r");
        if (f_mp4 == NULL)return 0;
        P1 = fopen(args[2], "w");
        if (P1 == NULL)return 0;
        while (!feof(f_mp4))
        {
            char buf[1024] = { 0 };
            fgets(buf, sizeof(buf), f_mp4);
            if (args[3][0] == '0')//如果成立则加密
                encode(buf);
            else if (args[3][0] == '1')//如果成立就解密
                decode(buf);
            fputs(buf, P1);
        }
        fclose(f_mp4);
        fclose(P1);
    }

    超大文件排序

         有时候会对超大文件进行排序,我们的方法是先把超大文件读取到数组里,然后在再使排序算法对其进行排序,在写入到文件里。

    int main()
    {
        srand((unsigned int)time(NULL));
        FILE *p = fopen("a.txt", "w");
        if (p)
        {
            for (int i = 0; i < 1000; i++)
            {
                int seq = rand();
                char buf[100] = { 0 };
                sprintf(buf,"%d\n", seq);
                fputs(buf, p);
            }
            fclose(p);
        }
        FILE *p1 = fopen("a.txt","r");
        int arry[100] = { 0 };
        int index = 0;
        while (!feof(p1))
        {
            char buf[1024] = { 0 };
            fgets(buf, sizeof(buf), p1);
            arry[index] = atoi(buf);//把读出来的字符串转化为数组
            index++;
        }
        bubble(arry, index); //排序算法,此处需要自己写排序算法
        fclose(p1);
    }

    fprintf与fscanf函数

            fprintf格式化输出到一个流/文件中;函数原型为int fprintf( FILE *stream, const char *format, [ argument ]...),fprintf()函数根据指定的格式(format)向输出流(stream)写入数据(argument)。

           fscanf函数原型为 int fscanf(FILE * stream, const char * format, [argument...]); 其功能为根据数据格式(format)从输入流(stream)中读入数据(存储到argument);与fgets的差别在于:fscanf遇到空格和换行时结束,注意空格时也结束,fgets遇到空格不结束。

    //1.txt文件内容
    //2+3=
    //56+90=
    int main(){
        FILE *P = fopen("1.txt","r");
        FILE *P1 = fopen("2.txt", "w");
        while (!feof(P))
        {
            int a = 0;
            char b = 0;
            int c = 0;
            fscanf(P,"%d%c%d=", &a, &b, &c);//fscanf是从一个文件中读取字符串,并转义
            if (feof(P)) break;
            fprintf(P1, "%d%c%d=%d\n", a, b, c, (a + c));//fprintf和sprintf功能类似,只是目标是文件,而不是字符串
        }
        fclose(P);
        fclose(P1);
    }
    //本例子主要是读取文件里的年龄
    /*************txt文件内容*****************
    年龄=15
    年龄=89
    年龄=23
    ****************************************/
    int main(){
        FILE *p = fopen("1.txt", "r");
        while (!feof(p))
        {
            int age = 0;
            char buf[100];
            fgets(buf, sizeof(buf), p);
            sscanf(buf, "年龄=%d", &age);//sscanf是从一个字符串中读取字符串,并转义
            printf("%d\n", age);
        }
        getchar();
        fclose(p);
    }
  • 相关阅读:
    模板方法模式
    策略模式
    代理模式
    单例模式
    工厂模式
    服务器负载过高问题分析
    支付宝APP支付开发- IOException : DerInputStream.getLength(): lengthTag=89, too big
    阿里云linux服务器挂载数据盘
    3.3.4.2选择特定行
    3.3.4.1选择所有数据
  • 原文地址:https://www.cnblogs.com/latencytime/p/10231205.html
Copyright © 2011-2022 走看看