标准IO(Ubuntu)

  • 标准IO

    • 什么是标准IO

      • 头文件stdio.h

        • 用的最多的两个输入输出函数printf和scanf

          • 针对终端的输入输出函数
      • 数据输入到特定的文件需要的条件

        • 需要知道指定文件的文件名和位置

        • 输入到文件中的内容

      • 指定文件

        • fopen函数

          • FILE *fopen(const char *pathname, const char *mode)
        • 功能描述

          • 打开pathname文件,并将其关联到一个流指针,该指针通过返回值的形式返回值。

            • 通过操作这个返回出来的流指针,就相当于在操作文件本身
          • 文件会以mode的方式打开,mode有以下几种情况

            • r:以只读的形式打开文件,如果文件不存在,就会打开失败,fopen就会返回NULL,文件打开成功后,光标位于文件的最开头(即第一个数据的前面)

              • 补:光标位于文件的最末尾指文件的最后一个字符的后面(及文件的结束符)
            • r+:以读写的形式打开文件,其他和r一样

              • 但是r+打开的文件读写同时存在,并且光标独立管理
            • w:以只写的形式打开文件,若文件不存在,则创建后打开,若文件存在,则清空文件打开(清空操作),文件打开后,光标位于文件的开头

              • 补:w打开文件,也存在失败的可能,即文件打开数量超过系统上线(1024个)

              • 可通过shell指令ulimit -a查看打开文件数量 同理文件打开失败会返回NULL

            • w+:以读写的方式打开文件,其他的和w一样

              • 读写光标独立管理
            • a:以追加的方式打开文件

              • 若文件不存在,则创建文件后打开,若文件存在,则直接打开(无清空操作)

              • 文件打开后光标置于文件末尾

            • a+: 以追加和读的方式打开文件

              • 注:读光标是在文件的开头,写文件是在文件的结尾 两个光标独立管理
          • IO操作与数据库:IO没有办法直接删除某一项数据,只能通过逻辑操作来实现

      • 当不再使用文件时关闭文件

        • int fclose(FILE *stream);

        • 功能描述:传入一个文件的的流指针,关闭该文件

      • 3个特殊文件流指针

        • FILE *stdin:标准输入流
    • 文件的输入输出函数

      • 第一组针对文件的输入和输出函数

        • fprintf();

          • int printf(const char *format, ...);

            • 调用形式: printf("%d helloworld\n",123) 功能描述:printf默认使用stdout标准输出流 printf会将 format 中的内容通过流指针stdout标准输出流,输出到终端上面去
          • int fprintf(FILE *stream, const char *format, ...);

            • 功能描述:fprintf会将format中的内容,通过流指针stream,输出到指定的文件中去 调用形式: fprintf(stream,"%d helloworld",345); 也就是说,当fprintf的第一个参数,写成stdout的话,效果等同于printf
          • int sprintf(char *str, const char *format, ...);

            • 功能描述:将format中内容,写入到 str指向的字符数组里面去,实现一个任意数据类型转换成字符串的效果
        • fscanf();

          • int scanf(const char *format, ...);

            • 功能描述:默认使用流指针 stdin,从stdin所代表的终端中,读取数据,将读取到的数据写入到format中格式占位符所代表的变量中去
          • int fscanf(FILE *stream, const char *format, ...);

            • 功能描述:从流指针 stream所指向的文件中,读取数据,将读取到的数据写入到format中格式占位符所代表的变量中去

              • 注意:使用fscanf吸收文件中的所有内容的时候,如何确定循环次数

              • a:通过fscanf的返回值来确定循环次数

              • fscanf成功返回成功吸收的数据的项数,也就是格式占位符的数量

              • 失败吸收数据或者读取到了文件的末尾,返回 EOF (-1)

              • b:通过函数 feof 来确定是否读取到了文件的末尾

          • int feof(FILE *stream);

            • 功能描述:传入等待判断是否读取到文件末尾的文件流指针,如果该文件已经被读取到了末尾,则返回1,没有读取到末尾,返回0

              • 注意:fscanf使用%c的时候,能够吸收空格和回车
          • 文件内容结束标志

            • res = fscanf(fp,"%s",buf);

              • if(i != res)

                • i:fscanf第二个参数格式占位符的数量
              • if(res == EOF)

              • if(feof(fp) == 1)

          • int sscanf(const char *str, const char *format, ...);

            • 功能描述:从指针str所指向的字符数字/字符串中,读取数据,将读取到的数据写入到format中格式占位符所代表的变量中去。

            • 最终实现了:将字符串类型的数据,转换成任意类型的数据

      • 第二组针对文件的输入输出函数

        • fputc();

          • int fputc(int c, FILE *stream);

          • 功能描述:将参数c输出到stream所指向的文件中

          • 返回值

            • 成功返回写入的字符,以unsigned char 形式返回,失败返回则EOF(-1)

            • fputc('x', stdout)等价于fprintf(stdout,"%c",'x');

        • fgetc();

          • int fgetc(FILE * stream);

          • 功能描述

            • 从stream指向的文件中读取一个字节的数据,并以返回值的形式。返回读取到的数据

            • 返回值

              • 成功读取,以unsigned char 的形式,返回读取到的字符数据,

              • 失败返回 -1

        • 返回值不能用unsigned char 接收

          • 返回值为负一会被强转为255
      • 第三组针对文件的输入输出函数

        • fputs

          • int fputs(const char * s, FILE *stream);

          • 功能描述

            • 将字符串或字符数组S写入到文件中

              • S最后的结束符不会写入文件
          • 参数1

            • 输入到文件中的字符串/字符数组
          • 参数2

            • 指定的被输出的数据文件
          • 返回值

            • 成功:返回写入字符的个数

            • 失败返回EOF

              • 文件末尾
        • fgets

          • char *fgets(char *s, int size, FLIE *stream)

          • 功能描述

            • 从stream指向的文件中,读取最多size - 1个字节的数据,然后将其写入s所指向的字符数组中,所有数据写入完成后,会再次写入一个结束符。

              • 当手动输入字节大小时需预留1个字节的空间用于存放结束符
          • 注意

            • fgets只读取一行内容(回车结束)或'\0'或文件结束符,或者当读取字节大小达到size - 1就会结束读取
          • 参数1

            • 存放读取到的数据的数组
          • 参数2

            • 存放读取的字节大小,函数内部会自动将size -1 ,即读取size - 1个字节的数据
          • 参数3

            • 从stream指向的文件中读取数据
          • 返回值

            • 成功读取,返回第一个参数(字符串数组名)

            • 失败或文件末尾

              • 返回NULL或EOF
          • 故使用fgets读取文件中内容时需循环读取

            • 循环结束条件

              • char *res = fgets(); if(res == NULL){break;} if(feof(fp) == 1){break;}
      • 第四组针对文件的输入输出函数

        • fwrite

          • size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

          • 功能描述

            • 将nmemb个数据块(每块size大小)写入stream所指文件中,数据块首地址由ptr决定
          • 参数1

            • 想要写入文件中的数据块的首地址
          • 参数2

            • 每个数据块的大小
          • 参数3

            • 数据块的个数
          • 参数4

            • 指向文件的流指针
          • 返回值

            • 成功返回写入数据块的数量

            • 失败返回0或小于nmemb的一个数据

          • 将数据写入文件中使用的是数据流(二进制字节流)

            • 文件流

              • 前面学习的fprintf,fputc,fputs无论什么数据,都会以字符串的形式传入文件
            • 数据流

              • 只有字符或字符串,在文件中是以字符串的形式传入,其余以二进制方式存在
        • fread

          • size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

          • 功能描述

            • 从stream指向的文件中,读取nmemb个数据块,每个数据块size大小,然后将读取到的数据块存入ptr指向的内存中
          • 第一个参数

            • 读取数据的存放空间
          • 第二个参数

            • 一个数据块的字节大小
          • 第三个参数

            • 数据块的数量
          • 第四个参数

            • 传入的文件流指针
          • 返回值

            • 通过if语句对其结束进行判断

            • 成功返回读取数据块的数量,

            • 失败返回0或nmemb的第一个数据

          • 注意

            • fread读取数据块时,可能导致某个数据块出现文件结束符,从而导致fread函数返回0,我们需要做到

              • 数据明确时严格按照数据字节大小进行读取

              • 数据块大小不明确时,1个字节一个字节读取

            • fwrite将数据写入文件中,使用的是数据流,

    • 光标偏移函数

      • fseek

        • int fseek(FILE *stream, long offset, int whence)

        • 将文件的光标位置从whence位置偏移offset个字节

        • 参数一

          • 文件流指针
        • 参数二

          • 光标偏移量,+为从左向右偏移,-为从右向左偏移
        • 参数三

          • 偏移起始位置

            • SEEK_SE

              • 文件开头
            • SEEK_CUR

              • 文件当前位置
            • SEEK_END

              • 文件末尾(结束符脸上)
        • fseek读写光标是一起偏移的,不做区分

    • 标准IO缓存区

      • printf换区验证

        • printf("hello"); while(1);

        • 上述代码运行之后,发现终端并未出现"hello" 说明其没有写入终端文件,而是进入printf缓存区

        • 缓存区刷新时缓存区的内容进入终端

        • 缓存区刷新条件

          • 遇到回车('\n')

          • 缓存区满刷新

            • while(1){ printf("hello world") usleep(8000); }

              • usleep

                • 休眠(us)
              • sleep

                • 休眠(s)
          • 程序结束

          • IO切换

            • 输入输出切换

              • stdout函数

                • getchar()

                • get

              • stdin函数

          • 文件关闭刷新

            • fclose
          • 调用函数fflush(传入流指针),手动刷新

            • fflush(stdin);
        • scanf缓存区

          • 当缓存区存在数据时,会读取数据,将数据取走

          • 若数据不能读取,则会重复读取

      • 标准IO中的缓存区分类

        • 行缓存

          • 1024字节

          • printf向终端输出的数据就是行缓存

          • 对应stdou函数

        • 全缓存

          • 4096字节

          • fprintf,fputc,fputs,fwrite这些向外部文件输入内容的用的都是全缓存

          • 刷新条件比行缓存少一个'\n'

        • 无缓存

          • perror使用标准错误流向终端输出错误信息用的是无缓存,没有刷新规则
        • 标准IO的所有函数都在流指针所指向的内存空间里

      • 计算缓存区大小

        • 直接让 文件流指针._IO_buf_end - 文件流针._IO_buf_base

        • 注意:使用这种方法计算缓存区的话 一定提前激活一下缓存区(调用函数)

作业

 #include <myhead.h>                                      
 int main(int argc, const char *argv[])
 {
     printf("__-__-__-__");
     int i = 1;
     do
     {
         fflush(stdout);
         sleep(1);
         for(int i = 0; i < 11; i++)
         {
             printf("\b");
         }
         switch(i)
         {
         case 1:printf("1_-__-__-__");break;
         case 2:printf("12-__-__-__");break;
         case 3:printf("12-3_-__-__");break;
         case 4:printf("12-34-__-__");break;
         case 5:printf("12-34-5_-__");break;
         case 6:printf("12-34-56-__");break;
         case 7:printf("12-34-56-7_");break;
         case 8:printf("12-34-56-78");break;
         }
         i++;
     }while(i != 9);
 
 
     return 0;
 }
相关推荐
Mae_cpski18 分钟前
【Threejs学习】材质灯光投影
前端·学习·3d
BJ-Giser19 分钟前
cesium 水波纹扩散圆材质
前端·javascript·cesium
笑毅21 分钟前
ant-design-vue的table组件的首列复选框设置问题,包括设置默认选中,设置禁选条件
前端·javascript·vue.js
JAMJAM_NoName30 分钟前
【前端开发】国际化开发工具i18n的使用教程
前端·javascript·vue.js·国际化开发
podoor31 分钟前
wordpress判断是否为首页
前端·wordpress
易雪寒42 分钟前
CSS系列之Float浮动(二)
前端·css
沐爸muba1 小时前
今日算法:蓝桥杯基础题之“门牌制作”
前端·javascript·算法·蓝桥杯
533_1 小时前
[vue] 按钮限制连点
前端·javascript·vue.js
计算机程序设计开发1 小时前
基于Angular技术的MES系统基础管理功能的实现
前端·javascript·spring boot·angular.js·计算机毕业设计
可爱的秋秋啊1 小时前
Vue3常见知识**MS【4】
前端·javascript·vue.js