C语言文件操作的那些细节

C语言文件常用操作

一、FILE结构体

    FILE *fp = fopen("YKDog.txt", "r");

FILE 是一个结构体。文件是存放在物理磁盘上的,包括文件控制块(FCB)数据块。文件控制块通常包括文件权限、日期(创建、读取、修改)、拥有者、文件大小、数据块信息。数据块用来存储实际的内容。对于打开的文件,操作系统是这样管理的:

系统维护了两张表,一张是系统级打开文件表,一张是进程级打开文件表(每个进程有一个)

FILE结构体

我们不能直接操作系统级的文件表, 所以我们可以通过进程级文件表指针间接操作FCB。FILE结构体中的_file指针指向了进程级文件表, 而进程级文件表保存了指向系统级文件表的指针和其他信息。简而言之,操作FILE结构体,就间接的操作了文件。而操作FILE结构体, 我们采用了FILE *fp这个指针。

二、fopen函数

    FILE *fp = fopen(文件路径,操作权限)

权限设置如下:

权限字符 含义
r 如果路径文件不存在就会返回NULL,不存在不会创建文件。
r+ 不存在报错并且不会创建
w 如果文件不存在不会返回NULL,并且会创建文件
a 如果文件不存在不会报错, 并且会自动创建文件
a+ 如果文件不存在不会报错自动创建, 在末尾追加不会覆盖
w+ 不存在不会返回NULL报错, 自动创建,会清空后覆盖

二、fputc和fgetc函数

fputc返回值是写入成功的字符,如果写入失败返回EOF(-1的一个宏, end of file缩写)

fputc(字符, FILE*)

fgetc(FILE*)返回一个读到的字符, 结尾或出错(比如权限不够)返回EOF
看一个练习就知道怎么用了

练习:写入a-z的字符到YKDog.txt中,再用fgetc读取

code

       
   FILE *fp = fopen("YKDog.txt", "w");
   //路径 + 写权限
   if (fp == NULL) printf("error");
   
   for(char i = 'a'; i <= 'z'; i++){
       printf("%-3c", fputc(i, fp));
       //返回值是写入成功的字符
   }
   printf("\n");

   fclose(fp);
   
   FILE *fpr = fopen("YKDog.txt", "r");
   if (fp ==  NULL) printf("error");
   char ch;
   while((ch = fgetc(fp)) != EOF){
       printf("%-3c", ch);
   }   
   

   fclose(fpr);

结果:

a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z 

a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z

要特别注意的是写完一定要fclose不然不会把缓存中的数据写到磁盘上, 导致下边的读取出问题。

返回值总结:fputc 返回值是写入成功的字符,失败返回EOF。fgetc返回值是读取到的字符,失败或结束返回EOF

三、feof判断文件流结束标识函数

函数避免使用

feof如果到结束标识就返回1, 否则返回1.

练习使用fgetc获得之前YKDog中的a-z

易错思路:
如果没有遇到结束标识就一直打印。刚好结束就不执行while中语句了。然而忽略了这个延迟, 标志位要到下一次读取(fgetc)的时候才会修改为1.下一次读取, 已经超出范围。

    FILE *fp = fopen("YKDog.txt", "r");
    if (fp == NULL) printf("error");
    
    while(!feof(fp)){

        printf("%c ", fgetc(fp));

    }

    fclose(fp);

a b c d e f g h i j k l m n o p q r s t u v w x y z ?

修改思路,既然延迟一个读写修改结束单位。那我就多读取一次

    FILE *fp = fopen("YKDog.txt", "r");
    if (fp == NULL) printf("error");

    char ch = fgetc(fp);
    while(!feof(fp)){

        printf("%c ",ch );

        ch = fgetc(fp);

    }

    fclose(fp);

四、fputs和fgets

fputs 是写一个字符串到文件中。
fpusts(字符串首地址, FILE *) 返回值是 如果写入成功返回0 或字符串的长度(平台不一样结果不一, 肯定是非负), 失败返回EOF.\n等字符也会写入。并且自动加上\0

       FILE *fp = fopen("YKPig.txt", "w");
   if(fp == NULL) printf("error");
   
   int ret=fputs("Hello, YKPig\n", fp);

   printf("ret = %d\n", ret);

有的操作系统比如centOS, MacOS会在文本编辑结束后会自动在其后加入\n也就是0a。windows不会

fgets(buf, 10, FILE *fpr)
简单的说吧, 把fpr文件内容每次10-1个字节读入到buf中。如果遇到\n或者文件结束 结束读取。每读取一次在内容后自动添加\0。

返回值是每次成功读到的 保存到buf中字符的首个地址。失败返回NULL

总结:
fgets 函数返回有三个条件:

  • 读 n-1 个字符前遇到\n,读取结束。
  • 读 n-1 个字符前遇到 EOF,读取结束。
  • 最多读 n-1 个符。
  • 在每读一行后自动加’\0’。

Mac下读内容

Mac系统存储的数据

.表示\n换行。最后一个是系统加的

    FILE *fpr = fopen("YKBird.txt", "r");
    if (fpr == NULL) printf("error");
    
    char buf[1024];

    while(fgets(buf, 10, fpr) !=NULL  ){

        printf("%s=", buf);
    }

结果

123456789=abcdefg
=123456789=0
=abcdefg
=

注意:

  • 打印的时候是遇到\n才打印的。
  • buff中不是存储所有的结果。是存储每次读到的结果。
小码哥iOS
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • C/C++输入输出流总结 前两天写C++实习作业,突然发现I/O是那么的陌生,打了好长时间的文件都没有打开,今天终...
    LuckTime阅读 1,807评论 0 6
  • 概述 在C语言文件输入和输出操作的学习心得(一)介绍了一些关于C语言文件写入的知识,本文将对前文进行延伸。前文的实...
    nothingCheung阅读 1,559评论 3 4
  • 1.创建文件夹 !/bin/sh mkdir -m 777 "%%1" 2.创建文件 !/bin/sh touch...
    BigJeffWang阅读 10,487评论 3 53
  • 昨天,看到点评官诸慧的文章《码字的苦恼》也有同感,坚持写简书两个多月了,我的写作水平提高了多少呢?形成写作习惯了吗...
    鲁郭杰阅读 226评论 0 3
  • 最近,总是想些关于爱情的事情,也许现在单身想有个对象吧。 心里又告诉自己,何必要急着去恋爱呢?每天到处看看女孩儿...
    忆上阡陌阅读 219评论 0 1

友情链接更多精彩内容