zoukankan      html  css  js  c++  java
  • 文件

    有一点感觉很重要,那就是用a或a+等方式打开文件,然后紧接着用ftell(fp);获取文件位置指针,发现都是0,但是发现当第一次写的时候文件位置会移到文件尾。

    读文件

    出错返回NULL

      FILE *fp=fopen("D:\demo.txt","r");

    打开方式

    1.如何没有b,则是以文本方式打开文件

    2.凡是以r打开文件,文件必须存在

    3.+是读/写

      r     读方式打开 只允许读,不允许写   

      r+  读/写文件    允许读和写     

      rb+  读/写文件      允许读和写   

      rt+     读/写文件    允许读和写         

      w  只写方式打开   文件存在则清0,不存在创建文件

      w+    读/写方式打开  文件存在则清0,不存在创建文件

      wb  以只写方式打开或创建文件  只允许写

      wb+ 以读/写方式打开或创建文件  允许读和写

      wt+  以读/写方式打开或创建文件  允许读和写

      a  以追加方式打开只写文件  存在则写入的数据会追加到文件尾,不存在创建

      a+  以追加方式打开读/写文件  存在则写入的数据会追加到文件尾,不存在创建

      ab+ 以读写方式打开  允许读或在文件尾追加

      at+  以读/写方式打开  允许读或在文件尾追加

    把一个文本文件读入内存时,要将ASCII码转换成二进制码,而把文件以文本方式写入磁盘时,也要把二进制码转换成ASCII码,因此文本文件的读写要花费较多的转换时间。对二进制文件的读写不存在这种转换。

    DOS和Windows系统使用CRLF(0x0D 0x0A) 双字节作为文本文件换行符,而Unix文本文件的换行符只有一个字节LF(0x0A) 。在C语言中,也是以LF即' '为换行符。

    在Unix和其他一些系统中,沒有文本方式和二进制方式的区分,使不使用'b'标志都是一样的

      

    关闭文件

    成功返回0,失败返回非0

      int fclose(FILE *fp);

    以字符方式读写文件(fgetc()和fputc())

    int fgetc(FILE *fp);  //成功返回读取到的字符,失败返回EOF(EOF不绝对是-1,这要看编译器的实现)

                不读取文件的最后结束标志,用putc(ch,stdout);或putchar(ch);输出最后没有换行

    这里我们可以借助while((fp=fgetc(fp))!=NULL){  putchar(ch); } 来获取读到字符,但是由于fgetc()读取失败也是返回EOF,无法判断是否读取到文件尾,我们可以通过feof()和ferror()来进行判断是否真的读取到文件尾。

      int feof(FILE *fp);      int ferror(FILE *fp);     //正确都是返回0,否则返回非0

       使用示例:

                if(ferror(fp))
                      printf("文件出错! ");
                else
                      printf("文件成功! ");

    int putc(int ch,FILE *fp);   //成功返回要写入的字符,失败返回EOF

       使用示例:

          #include<stdio.h>
          int main(void)
          {
                FILE *fp;
                char ch;

               fp=fopen("words.txt","wt+");

                puts("请输入一个字符串");
                while((ch=getchar())!=' ')        //这里发现可以录入汉字“你好”到fp所指的文件中
               {
                    putc(ch,fp);
                }

                return 0;
         }

         然后把上面的程序改为

          fopen("words.txt","r");

          while((ch=getc(fp))!=EOF)

          {

            putc(ch);               //这里发现,是可以输出文件中的中文的

          }  

    以字符串的方式读取文件

    在c语言中没有按行读取文件的函数,可以把fgets()中的参数n设置的足够大,以至于可以读取一行的数据来代替读取一行的数据。

    fgets()函数遇到换行会将换行读取到字符串中,然后在字符串末尾添加;而gets()函数会忽略换行。

    char *fgets(char *str,int n,FILE *fp);    //读取成功返回字符串的首地址,即str,否则返回NULL。读取到的字符串末尾自动添加,也                    就是说实际读取到的是n-1个字符。遇到 则自动结束。

      示例:

          #include<stdio.h>
          int main(void)
          {
              FILE *fp;
              char ch[40];

              fp=fopen("words.txt","r");

             while(fgets(ch,40,fp)!=NULL)       //这里发现如果把40改为3,仍然可以输出第2个字符之后的数据,出现数组越界,但                          是在vc6.0下没有报错
              {
                  fputs(ch,stdout);     //这里一样可以一行一行输出文件中的内容
              }

              return 0;
          }

    int fputs(char *str,FILE *fp);     //写入成功返回非负,否则返回EOF

     多行读取

    size_t fread ( void *ptr, size_t size, size_t count, FILE *fp );
    size_t fwrite ( void * ptr, size_t size, size_t count, FILE *fp );
    count是数据块的块数
    size是读取的字节数
    理论上,每次读写 size*count 个字节的数据
    size_t 是在 stddef.h 头文件中使用 typedef 定义的数据类型,表示无符号整数,也即非负数,常用来表示数量。
    返回成功读写的块数,也即 count。如果返回值小于 count:
    • 对于 fwrite() 来说,肯定发生了写入错误,可以用 ferror() 函数检测。
    • 对于 fread() 来说,可能读到了文件末尾,可能发生了错误,可以用 ferror() 或 feof() 检测。
    fwrite()/fread() 函数直接操作字节,建议使用二进制方式打开文件。
    示例1如下:
    #include<stdio.h>
    #define N 5

    int main(void)
    {
        //从键盘录入的数据放入a,从文件读取的数据放入b
        int a[N],b[N];
        int i,size=sizeof(int);
        FILE *fp;

        if((fp=fopen("words.txt","rb+"))==NULL)
        {
            printf("不能打开文件! ");
            exit(1);
        }
        
        //从键盘输入数据,保存到数组中
        for(i=0;i<N;i++)
        {
            scanf("%d",&a[i]);
        }
        
        //将数据写入到文件中
        fwrite(a,size,N,fp);

        //将文件指针重新定位到文件开头
        rewind(fp);

        //从文件中读取内容保存到数组b
        fread(b,size,N,fp);

        for(i=0;i<N;i++)
            printf("%d ",b[i]);

        fclose(fp);
        fp=NULL;

        return 0;
    }

    示例2:
    #include<stdio.h>

    #define N 2

    struct stu{
        char name[10];
        int num;    //学号
        int age;
        float score;
    }boya[N],boyb[N],*pa,*pb;

    int main(void)
    {
        FILE *fp;
        int i;
        pa=boya;
        pb=boyb;

        if((fp=fopen("words.txt","wb+"))==NULL)
        {
            printf("不能打开文件! ");
            exit(1);
        }

        //从键盘输入数据
        printf("输入数据: ");
        for(i=0;i<N;i++,pa++)
        {
            scanf("%s %d %d %f",pa->name,&pa->num,&pa->age,&pa->score);
        }

        //将数组baya的数据写入文件
        fwrite(boya,sizeof(struct stu),N,fp);
        //将文件指针重置到文件开头
        rewind(fp);
        //从文件读取数据并保存数据至boyb
        fread(boyb,sizeof(struct stu),N,fp);

        //输出数组boyb中的数据
        for(i=0;i<N;i++,pb++)
        {
            printf("%s %d %d %f ",pb->name,pb->num,pb->age,pb->score);
        }

        fclose(fp);
        return 0;
    }
    格式化读写文件
    int fscanf ( FILE *fp, char * format, ... );
    int fprintf ( FILE *fp, char * format, ... );
    成功时返回成功的字符个数。
    示例如下;





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

    #define N 2

    struct stu
    {
        char name[10];
        int num;
        int age;
        float score;
    }boya[N],boyb[N],*pa,*pb;

    int main(void)
    {
        FILE *fp;
        int i;
        pa=boya;
        pb=boyb;
        if((fp=fopen("words.txt","wt+"))==NULL)
        {
            printf("²»ÄÜ´ò¿ªÎļþ£¡ ");
            exit(1);
        }
        
        //´Ó¼üÅ̶ÁÈëÊý¾Ý£¬±£´æµ½boyaÖÐ
        printf("ÊäÈëÊý¾Ý£º ");
        for(i=0;i<N;i++,pa++)
        {
            scanf("%s %d %d %f",pa->name,&pa->num,&pa->num,&pa->score);
        }

        pa=boya;
        //½«boyaÖеÄÊý¾ÝдÈëµ½ÎļþÖÐ
        for(i=0;i<N;i++,pa++)
        {
            fprintf(fp,"%s %d %d %f ",pa->name,pa->num,pa->age,pa->score);
        }

        rewind(fp);

        for(i=0;i<N;i++,pb++)
        {
            fscanf(fp,"%s %d %d %f ",pb->name,&pb->num,&pb->age,&pb->score);
        }

        pb=boyb;

        for(i=0;i<N;i++,pb++)
        {
            printf("%s %d %d %f ",pb->name,pb->num,pb->age,pb->score);
        }

        fclose(fp);
        return 0;
    }

    对文件随机进行读写

    void rewind ( FILE *fp );
    int fseek ( FILE *fp, long offset, int origin );

    在fseek()函数中,origin的使用有以下3中方式。(值得说明的是,fseek一般用于二进制文件,如果是文本文件,由于要进行转换
    所以计算位置容易出错)



    获取文件的大小
    1.可以通过打开文件,然后利用fseek()跳转到文件尾,然后通过ftell()函数来获取文件的大小。
    缺点是ftell()函数的返回值是long,如果是4个字节的大小的话,文件的大小不超过2个G还可以应付,太大时就不行了。
    2.超大文件还可以通过fsetpos和fgetpos获取文件大小
    缺点是,它需要加载文件到内存中,当文件太多时,会比较耗时。
    3.直接读取文件信息获取文件大小,在linux下可以使用如下:
    1. #include <sys/stat.h>  
    2. int file_size2(char* filename)  
    3. {  
    4.     struct stat statbuf;  
    5.     stat(filename,&statbuf);  
    6.     int size=statbuf.st_size;  
    7.   
    8.     return size;  
     
     
  • 相关阅读:
    Penetration Test
    Penetration Test
    Penetration Test
    Penetration Test
    controller配置方式总结(继上)
    架构师的自我修养
    SpringMVC快速入门
    第十六章:字节流与字符流
    第十五章:文件操作
    第十四章:类库使用案例分析
  • 原文地址:https://www.cnblogs.com/xiaoshi-com/p/5749444.html
Copyright © 2011-2022 走看看