zoukankan      html  css  js  c++  java
  • c语言学习之基础知识点介绍(十六):文件操作

    一、文件的分类

           1、文本文件:打开之后能看得懂的文件

           2、二进制文件:打开之后看不懂,类似乱码之类的文件(视频,音频打开之后,能看、听,是应为电脑中装有播放器,播放器中含有解码器)。

    二、操作文件的步骤和方式

     操作步骤:

          1、打开文件

          2、操作文件

          3、关闭文件

     操作方式:

         文件流:操作文件就像水流一样,将一个大的文件分成一段一段的流过去。

         好处:分段操作,避免出现阻塞,卡死的发生。

    三、操作文件的函数

        1、fopen函数:
    /*
        fopen函数:
                fopen(路径,操作方式);
            fopen("/Users/ios/Desktop/1.txt", "r");
            绝对路径:文件的全路径
            相对路径:相对于当前文件所在的路径
     
        r: 以只读的方式打开文件,如果文件存在,返回文件的指针,如果不存在返回NULL
        w: 以只写的方式打开文件,覆盖原文件再返回文件指针,如果不存在则创建再返回文件指针
        a: 以追加的方式打开文件,如果文件存在,则追加原来的文件内容,如果不存在则创建文件。不管存在不存在最终都会返回文件指针
     
        r+:功能和r还是一样,只不过增加了写的功能
        w+:功能和w还是一样,只不过增加了读的功能
        a+:功能和a还是一样,只不过增加了读的功能
     
     
        以下不能单独用,要跟上面的嵌套一起
        t: 代表操作的是文本文件 (默认的)  rt  wt at rt+ wt+ at+
        b: 代表操作的是二进制文件      rb wb ab  rb+ wb+ ab+
     
        在mac或者Linux或者UNIX下,t和b没有区别。
     
        
    
     
        在windows下有区别
        
    
     
        区别就在于,如果你在windows下面,写入的是文本文件,那么会把所有的换行或者说所有的
    替换成
    ,二进制不会替换。
     
         在mac或者Linux或者UNIX下,无论写入文本文件还是二进制文件,
    都不会做任何替换。
     
     文件指针就叫 FILE指针。 注意:四个字都要大写。
    
    
    用r打开,文件不存在返回NULL(0).
        注意:NULL 就是 0  16进制0x0
    如果不存在,就不能读取里面的内容,所以我们在读取之前应该判断是否不为NULL .
    */
    
    #include <stdio.h>
    #include <string.h>int main(int argc, const char * argv[]) {
        FILE *fp; //变量名叫fp  是FILE指针
        fp = fopen("/Users/ios/Desktop/1.txt", "r");
        //FILE *fp = fopen("/Users/ios/Desktop/1.txt", "r");
        fclose(fp);
        return 0;
    }
         2、fgetc函数
    /*
     fgetc函数:
            用法:fgetc(文件指针);
            作用:读取一个字符。
     
            返回值读取到的字符。
     
            例:char ch = fgetc(fp);
     
        如果文件读取到末尾会读取到一个特殊字符叫 EOF,所以如果读取到EOF了,那么代表结束了。
     
        EOF就是文件结束的标识符,读取到EOF就代表文件读取完了。
    
     fputc:
        语法:fputc(要写入的字符,文件指针);
        作用:写入一个字符到文件
    */
    #include <stdio.h>
    #include <string.h>
    
    void readFile(){
        FILE *fp;
        //假设文件内容为  abc
        fp = fopen("/Users/ios/Desktop/1.txt", "r");
        if (fp != NULL) { //需要判断文件指针不为NULL才能操作
            //操作
            /*
             char ch = fgetc(fp);
             printf("%c
    ",ch);              //a
             
             char ch2 = fgetc(fp);            
             printf("%c
    ",ch2);              //b
             
             char ch3 = fgetc(fp);
             printf("%c
    ",ch3);              //c
             */
            
            while (1) { //因为不知道文件有多少字符,所以死循环
                char ch = fgetc(fp);  //读取字符·
                if (ch == EOF) { //判断读取的字符是不是文件末尾
                    break; //如果是则退出循环
                }
                printf("%c",ch); //否则打印出读取到的内容
            }
            fclose(fp); //一定要加fclose
        }
    }
    
    int main(int argc, const char * argv[]) {
       
        return 0;
    }

         3、fputc函数

    /*
     fputc:
        语法:fputc(要写入的字符,文件指针);
     
        作用:写入一个字符到文件。
    */
    void writeFile(){
        FILE *fp = fopen("/Users/ios001/Desktop/1.txt", "w"); //
        if(fp != NULL ){
            char str[] = "hello";//数组长度为6
            int len = strlen(str); //计算字符串实际长度 只能算得5
            for (int i = 0; i<len; i++) {
                //循环打印每个字符
                fputc(str[i], fp); //str[0],str[1],str[2],str[3],str[4]
            }
            //操作文件
            /*
             fputc('h', fp);
             fputc('e', fp);
             fputc('l', fp);
             fputc('l', fp);
             fputc('o', fp);
             */
            
            //操作完成的提示
            printf("结束!");
            
            //关闭
            fclose(fp);//只有在关闭之后,文件中才会有写入的文本。
        }
    }
    
    
    
    
    int main(int argc, const char * argv[]) {
        FILE *fp = fopen("/Users/ios/Desktop/1.txt", "a"); //追加
        if(fp != NULL ){
            char str[] = " shanghai";//数组长度为8
            int len = strlen(str); //计算字符串实际长度 只能算得5
            for (int i = 0; i<len; i++) {
                //循环打印每个字符
                fputc(str[i], fp); //str[0],str[1],str[2],str[3],str[4]
            }
            //操作文件
            /*
            fputc('h', fp);
            fputc('e', fp);
            fputc('l', fp);
            fputc('l', fp);
            fputc('o', fp);
            */
            
            //操作完成的提示
            printf("完成!");
            
            //关闭
            fclose(fp);
        }
        return 0;
    }

          4、fputs和fgets函数

    /*
     之前用fgetc和fputc只能一个一个字符的读,或者写,没法一下子读取一串字符串
     
     所以如果要用fgetc或者fputc必须循环读取
     
     所以我们需要一种非常方便读取或者写入一串字符串的方法
     fputs:
     
        fputs(字符串,文件指针);
        作用:写入一串字符串
        
        详解:把字符串写入到文件指针所指向的文件处
     
        例:fputs("我爱上海陆家嘴", fp);
     fgets:
     
        fgets(char数组地址, n, 文件指针);
     
        作用:读取一串字符串
     
        详解:把读取的字符,存到哪个数组里面,n代表一次读取几个字符,去哪个文件读
     
        注意:1、只能读到n-1个有效字符,因为还有一个字符帮你加''
                    2、如果读取到换行(
    ),那么会停止读取,然后把换行也读取来,并且在换行后面加
     
     
    读取多行:
        文件中的文本行数无法确定,所以需要一个循环(死循环)。
     
        判断读取到末尾:
                feof(文件指针);
                    如果返回的是1(真),代表读取到末尾。
                    如果返回的是0,代表没有到末尾。
     
    */
    
    #include <stdio.h>
    
    /**
     *  写入一串字符串
     */
    void writeString(){
        FILE *fp = fopen("/Users/ios/Desktop/1.txt", "w");
        if(fp != NULL){
            //写字符串
            fputs("我爱家乡妹子多", fp);
            printf("写完了
    ");
            fclose(fp);//立即写不要忘关闭,不然内容不会保存
        }
    }
    
    int main(int argc, const char * argv[]) {
        FILE *fp = fopen("/Users/ios001/Desktop/1.txt", "r");
        if(fp != NULL){
            char str[100];
            //
            while (1) {
                if(feof(fp)){ //如果为真,代表读取到末尾
                    break; //不需要继续读了,退出循环
                }
                fgets(str, 100, fp);
                printf("%s",str);
            }
            /*
            fgets(str, 100, fp); //因为你输入10,那么它只会读取99个有效的,还有一个位置是帮你加一个''
    
            printf("%s
    ",str);
            char str2[100];
            fgets(str2, 100, fp);
            printf("%s
    ",str2);
            */
            fclose(fp);//关闭文件
        }
        return 0;
    }

    补充一点:上面的代码判断某个变量是否为NULL的时候  都是 if(fp != NULL){},其实也可以这样写,if(fp){},应为 NULL 就是 0,也就是,当fp不为NULL的时候,就是

    4、fread和fwirte函数

    /*
     fgetc fputc  fgets  fputs:没有一段一段的读取文件
     
     fread和fwrite就比较像文件流一样一块一块的读或者写
     
     fread:
            fread(保存数据的地址,每块的字节大小,读取多少块,文件指针);
     
            1、它是读取文件的,而且任何问题都可以读,而且是分块读取。
     
                   1)、因为任何文件都可以读,所以保存数据的地址是可以不同类型。
            分块来读:所以要设置每块的字节大小,一共要读取多少块,去哪个文件读
     
        例:
                 char str[50];
                 fread(str, 3, 100, fp);
            注意:它只关心具体读的字节数,不会关心这些自己里面有没有换行
    
     fwrite:
            fwrite(写入的数据,每块的字节大小,写入多少块,文件指针);
            它是写入文件的。是分块写入。
            第一个是告诉系统,写入什么数据,第二个是告诉系统每块多少字节,第三个是告诉系统分多少块写入,第四个是写入到哪个文件
    
     注意:fwrite不要写的太大,要以实际为准,否则会写很多垃圾的二进制值进去,就打不开了
     
     数组名 == &数组名
    */
    
    #include <stdio.h>
    #include <string.h>
    
    void testFread(){
        
        
        FILE *fp = fopen("/Users/ios/Desktop/1.txt", "r");
        
        if(fp){
            
            //操作
            while (1) { //读取大文件时最好分很多段读取,这样可以有效节省内存,所以用循环
                
                if(feof(fp)){
                    
                    break;
                }
                
                char str[50] = {0};
                
                
                fread(str, 3, 3, fp);
                
                printf("%s",str);
                
            }
            
            fclose(fp);
        }
    }
    
    void testFwrite(){
        
        
        FILE *fp = fopen("/Users/ios/Desktop/1.txt", "w");
        
        if(fp){
            
            /*
             char str[] = "好就按我说结婚的撒娇看到过撒娇吧";
             
             int len = strlen(str);
             
             fwrite(str, 1, len, fp);
             */
            
            //        int num = 97;
            //
            //        fwrite(&num, 4, 1, fp);
            
            //        char ch = 'a';
            //
            //        fwrite(&ch, 1, 1, fp);
            
            char str[] = "10.333";
            
            fwrite(str, 1,strlen(str), fp);
            
            printf("成功了
    ");
            
            fclose(fp);
            
        }
    }
    
    int main(int argc, const char * argv[]) {
        
        FILE *fp = fopen("/Users/ios/Desktop/1.txt", "r");
        
        if(fp){
            
            int num;//存的是二进制,打开后会转成十进制的ascii
            
            fread(&num, 4, 1, fp);
            
            printf("%d
    ",num);
            
            fclose(fp);
        }
    
        return 0;
    }

    4、fprintf和fscanf函数

    /*
     
     printf:输出到控制台
     
     scanf: 从控制台输入
            scanf("格式化控制符",地址列表);
     
     
     fprintf:输出到文件(写入到文件)
     
                fprintf(文件指针,"格式化控制符",参数列表);
    
     fscanf:从文件输入(读取)
     
            fscanf(文件指针,"格式化控制符",地址列表);
     
    
    */
    
    #include <stdio.h>
    
    void testFprintf(){
        
        FILE * fp = fopen("/Users/ios/Desktop/1.txt", "w");
        
        if (fp) {
            
            fprintf(fp, "%d",99);
            
            fclose(fp);
        }
    }
    
    int main(int argc, const char * argv[]) {
    
        fprintf(stdout, "哈哈哈哈哈
    "); //跟printf没差别,stdout代表在控制台输出
        
        int num;
        fscanf(stdin, "%d",&num); //stdin在控制台输入
        
        printf("num=%d
    ",num);
        /*
        FILE * fp = fopen("/Users/ios/Desktop/1.txt", "r");
    
        if (fp) {
            
    //        int num;
    //        char ch;
    //        fscanf(fp, "%c帅%d",&ch,&num);
    //        printf("ch=%c    num=%d
    ",ch,num);//a 99
            
            char str[50] = {0};
            char str2[50];
            fscanf(fp, "%s
    %s",str,str2);
            
            
            puts(str);
            puts(str2);
            fclose(fp);
        }
        */
        return 0;
    }

    四、文件的复制

    /*
     //加密:
     //读取出来以后对每个字节做一个-1的操作
     //然后再写,就达到加密的作用了
     
     //解密:
     //先读出的加密,然后对每个字节进行+1的操作,然后再写,此时就可以看了
     
    */
    
    #include <stdio.h>
    
    int main(int argc, const char * argv[]) {
       
        //读取原文件
        FILE *fpRead = fopen("/Users/ios/Movies/高清无码声音又好听的片.mp4","r");
        
        //拷贝新的文件
        FILE *fpWrite = fopen("/Users/ios/Desktop/123/工作文件不要看.mp4", "w");
        if(fpRead){
            if(fpWrite){
                while(1){
                    if(feof(fpRead)){
                        break;
                    }
                    
                    char bytes[1024*1024]; //1m
                    //开始读
                    fread(bytes, 1024*1024, 1, fpRead);
                    
                    //开始写
                    fwrite(bytes, 1024*1024, 1, fpWrite);//写入到这个文件
                }
                
                printf("做完了!
    ");
                fclose(fpWrite);
            }
            fclose(fpRead);
        }
        return 0;
    }
  • 相关阅读:
    C# 操作配置文件
    C# Excel操作类
    没有找到 mspdb100.dll 的解决办法
    工厂方法模式
    .Net互操作2
    The certificate used to sign “AppName” has either expired or has been revoked. An updated certificate is required to sign and install the application解决
    手机抓包xcode自带命令行工具配合wireshark实现
    expecting SSH2_MSG_KEX_ECDH_REPLY ssh_dispatch_run_fatal问题解决
    使用ssh-keygen设置ssh无密码登录
    远程复制文件到服务器
  • 原文地址:https://www.cnblogs.com/bobo-pcb/p/4942723.html
Copyright © 2011-2022 走看看