你不是真的懂文件

  前言:提到文件我们能先想到什么呢,可能大家想到的就是那一个个磁盘中存储的东西,没错,磁盘中储存的就是文件。文件分为:①程序文件( 源程序文件 – 后缀名:.c,目标文件 – 后缀名:.obj , 可执行程序 – 后缀名:.exe) ②数据文件(文件内容不一定是程序,而是程序输入/输出时所要读取/存储的数据) ,本篇文章讨论的时数据文件。

目录

  一、文件名

  二、文件的打开与关闭              

  三、文件的读写      

  四、文件的种类 

  五、判定读取文件结束

  六、文件缓冲区


  一、文件名

   不知道大家有没有想过,姓名在我们生活中占了多大的作用,如果我们没有姓名的话,我们不禁会在心里产生这样一个疑问:

  因此,为了避免这种情况,我们有了姓名,而文件也是如此,每个文件都有一个唯一的标识,这个标识我们通常称为文件名。
   文件名:文件路径 + 文件名主干 + 文件后缀
   例:c:\pick\test.txt (由于转义字符,我们在VS中书写如下:c:\pick\test.txt )    

 二、文件的打开与关闭              

    平时我们打开文件用鼠标双击就打开了,但是我们在写代码时可不能这样打开哦,要写一个指令去①打开相关的文件
    说到打开,那就会产生另一个问题 -- ②以何种方式打开?这就像我们去别人家一样,我们可以打开房门在门外向房间里看一看,也可以走进去使用或者拿走家中的一些东西,当然,进去也有不同的方式(包括不限于强行闯入)。


    好了,我们先回到问题①,我们要使用文件,就必须先打开文件,因此,函数 fopen 就出现了。现在,我们可以讨论问题②了,我在这里列举了所有的打开方式,以及对应的操作,如下图:

   看似很多,其实我们可以很容易的总结。基础操作方式分为三个:r -- 读,w -- 写,a -- 追加,再此基础上加 b --- 二进制文件进行操作,加 + --- 进行读写,值得注意的是,不同的打开方式面对指定的文件不存在时产生的后果也不同:若有基础操作 r --- 报错,若有基础操作 b 和 a  --- 新建一个空白文件。   
   看到这里,大家可能也直到 fopen 的用法了,FILE*  fopen( 文件标识 , 打开方式) , 可以看到这个函数返回的是一个指针,指向的是 FILE 类型的数据,也就是文件。例:FILE* p = fopen(...) 

三、文件的读写      

   既然文件我们可以以不同的方式打开了,那么我们现在就可以对文件与内存进行操作了。
   1.文件的顺序读写:
    顺序读写,顾名思义,就是在文件指针默认的位置进行操作,我在这里列举了一些操作函数,        如下图:


     需要注意的是:fgetc函数在读取1个数据后文件指针会向后移动一个单位。
  补充:int sscanf(char* str , 格式....)  -- 将参数按照指定格式输入到str字符串中。
             int sprintf(char* str , 格式...) -- 将字符串按照指定格式输出到参数中。
   2.文件的随机读写:
        有顺序就会有随机。                                                                                                                                                              ---- 鲁迅
                               

   如果想要实现文件的随机读写,那么我们必须要控制文件的指针,这里就不得不提到 fseek 函数了。
     int fseek (FILE* p ,int size_t num,int origin) -- 流中从origin位置偏移num个字节。
    *
那么新的问题来了,这个origin位置要怎么确定呢?这里也列举了3个不同的位置:
                                                  SEEK_SET         文件开头
                                                  SEEK_CUR        指针的当前位置
                                                  SEEK_END        文件结尾

    有了这些,怕是指针飞的天花乱坠也能给找回来!
 

   3.ftell 与 rewind
  既然我们知道如何操纵文件指针了,那么就延伸出了一点知识:
    ①
ftelllong int ftell( FILE* p) --- 返回当前指针位置距文件开头的偏移量
    ②
rewindvoid rewind( FILE* p) --- 将文件指针直接移动到文件开头位置(你皮任你皮,一键到开头)

  四、文件的种类 

   文件可以划分为两种:①文本文件②二进制文件
   我们都知道数据在内存中是以二进制的方式存储的,如果输出到文件的过程中不转换的话,那么   就会以二进制的形式输出到文件中,文件自然就是二进制文件,而如果转换成ASCll字符进行存储   的话,那文件就是文本文件 。
我们也可以自己做个测试,如下图:
①以二进制的方式输出 1000 到文件 test10.31.txt 中

②打开对应的文件,这时我们可以清楚的看得到,这玩意我们不认识,因为里面存放的是二进制,我们又没有以二进制的方式打开,所以我们看不懂。

 


③我们按照如下步骤去以二进制的方式打开文件:
首先,右击源文件 -> 找到现有项 -> 双击对应的文件打开

打开后,我们右击该文件,单击打开方式,选择二进制方式打开,这样我们就看到了实际存储的数值,只不过这里是转换成十六进制了,我们稍加转换即可,由于是小端存储,因此实际存放的值是00 00 03 E8(地址从左到右逐渐减少),转换成十进制就是1000。

 


  五、判定读取文件结束
   1.feof 的错误理解:有很多人把 feof 作为判断判定文件否读取结束的函数,其实这是错误的,    feof 的作用是用于在读取文件结束时判断是什么原因都区结束的
   2.判断文件是否读取结束的函数:
    ① 文本文件:
     fgetc 、fgets
     fgetc:当fgetc返回的值为 EOF 时,文件读取结束。
     fgets:当fgets返回的值为 NULL 时,文件读取结束。
    ②二进制文件:
     判断二进制文件是否读取结束时,要看其返回值,返回值小于读取的个数就说明读取结束。
当判断文件是否读取结束后就可以使用 feof 对读取结束的原因进行判定了。
    feof:int feof(FILE* p ),若 feof 返回的值为非0,那么就说明当前光标后已经没有数值了。
例子如下:

int main()
{
  //打开一个文件
  FILE* p = fopen("F:\\en\\test.txt","r");
  //判断是否打开
  if(p == NULL)
  {
    perror("fopen:");
    return;
  }
  int c = 0;
  while(c = fgetc(p) != EOF)
  { 
   //输出文本中的字符
   putchar(c);
  }
  //读取结束、进行判断
  //判断结束是否是因为读取错误
  if(ferror(p)) //若文件读取产生错误,返回值为真
    printf("I/O error when reading\n ");
  //判断读取结束是否是因为读取到文件末尾
  else if(feof(p))
    printf("end of file reached successfully\n")
  return 0;
}

  六、文件缓冲区

    我们不管是从内存进行输入还是输出,这些数据并不是同步进行的,而是先要将数据存放到 输入/输出缓冲区 ,待缓冲区存满之后才会将数据进行 输入/输出 。此外,对缓冲区进行 fflush (刷新) or 遇到‘\n’(换行) 时也会将数据进行 输入/输出 。fclose文件也会对缓冲区进行刷新。
  代码奉上:

int main()
{
    FILE* p = fopen("F:\\en\\test.txt", "w");
    char arr[35] = "No way is impossbile to courage";
    if (p == NULL)
    {
        perror("fopen:");
        return;
    }
    //将字符串输出到文件中
    fputs(arr, p);
    //此时可打开文件,发现并没有数据写入
    
    //等待10秒
    printf("等待10秒\n");
    Sleep(10000);
    //刷新文件
    fflush(p);
    //再次等待10秒
    printf("文件以写入,再次等待10秒\n");
    Sleep(10000);
    //打开文件,看到数据写入
    //关闭文件
    fclose(p);
    p = NULL;
    return 0;
}

   以上,就是对文件操作的相关内容,有收获的朋友给个赞吧,创作不易(哭死)

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值