标准库IO编程

标准IO库是在系统调用下进行了一层封装,实现了更多的文件操作函数。虽然它的内部同样是调用系统函数,但由于他的用户缓冲区的原因,它的效率在大多数情况下都要比系统调用高。

常用函数

  • fopen()

    #include <stdio.h>
     
     FILE *fopen(const char *path, const char *mode);
    
    mode说明对应于open函数的flag值
    r只读O_RDONLY
    r+可读可写O_RDWR
    w只写(如果文件存在就清空从头开始写,如果文件不存在就建立)O_WRONLY|O_CREAT|O_TRUNC
    w+可读可写(如果文件存在就清空从头开始写,如果文件不存在就建立)O_RDWR|O_CREAT|O_TRUNC
    a只写,追加模式(如果文件不存在就建立)O_WRONLY|O_CREAT|O_APPEND
    a+可读可写追加模式(如果文件不存在就建立)O_RDWR

    虽然该函数无法手动设置文件权限(新建文件时),但其内部是一个默认权限的(0666)

  • fread(), fwrite(), 返回值为调用成功时数据项的数目

    #include <stdio.h>
    
      size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
      size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
      
      fread(buf, 1, 50, fq) 等价于 fread(buf, 50, 1, fq)
    
  • fseek()

      #include <stdio.h>
      
      int fseek(FILE *stream, long offset, int whence);
    
  • ftell(), 获取文件当前的读写位置偏移量

     #include <stdio.h>
     
      long ftell(FILE *stream);
    
  • feof(), )用于测试参数 stream 所指文件的 end-of-file 标志,如果 end-of-file 标志被设置了,则调用
    feof()函数将返回一个非零值,如果 end-of-file 标志没有被设置,则返回 0

    #include <stdio.h>
    
      int feof(FILE *stream);
    
  • fflush(), 刷新用户缓冲区,即将用户缓冲区的数据强制刷新到内核缓冲区。

    #include <stdio.h>
     int fflush(FILE *stream);  // 参数 stream 指定需要进行强制刷新的文件,如果该参数设置为 NULL,则表示刷新所有的 stdio 缓冲区。
    
  • 格式化输出

    	#include <stdio.h>
    
      int printf(const char *format, ...);
      int fprintf(FILE *stream, const char *format, ...);
      int dprintf(int fd, const char *format, ...);
      int sprintf(char *buf, const char *format, ...);
      int snprintf(char *buf, size_t size, const char *format, ...);  // 超出的部分会被丢弃
    
  • 格式化输入

    	#include <stdio.h>
    	
      int scanf(const char *format, ...);
      int fscanf(FILE *stream, const char *format, ...);
      int sscanf(const char *str, const char *format, ...);
    

其他

  • 每个进程都有独立的文件描述符表,文件描述符0,1,2是被系统分配了的(宏定义: STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO),分别是标准输入,标准输出,错误输出, 对应于标准库,也有全局变量stdin, stdout, stderr 分别是该三个IO的FILE指针,我们可以根据这三个指针配置标准输入输出,错误输出。eg:

      #include<stdio.h>
      int main(void)
      {
      	int x = 0;
      	printf("haha"); // 等价于fprintf(stdout, "haha"):
      	scanf("%d", &x); // 等价于fscanf(stdin, "%d", &x);
      	return 0;
      }
    
  • 库函数在用户内存空间也实现了自己的缓冲区,我们称之为stdio缓冲区。

  • setvbuf() , 设置stdio缓冲区模式,大小,起始地址

    #include<stdio.h>
    
    int setvbuf(FILE *stream, char *buf, int mode, size_t size);
    

    stream:FILE 指针,用于指定对应的文件,每一个文件都可以设置它对应的 stdio 缓冲区。
    buf:如果参数 buf 不为 NULL,那么 buf 指向 size大小的内存区域将作为该文件的 stdio 缓冲区,因为stdio 库会使用 buf 指向的缓冲区,所以应该以动态或静态的方式在堆中为该缓冲 区分配一块空间,而不是分配在栈上的函数内的自动变量(局部变量)。如果 buf 等 于 NULL,那么 stdio 库会自动分配一块空间作为该文件的 stdio 缓冲区(除非参数 mode 配置为非缓冲模式)。
    size:指定缓冲区的大小。
    mode:参数 mode 用于指定缓冲区的缓冲类型,可取值如下:

    • _IONBF:不对 I/O 进行缓冲(无缓冲)。意味着每个标准 I/O 函数将立即调用 write()或者 read(),并且忽略 buf 和 size 参数,可以分别指定两个参数为 NULL 和 0。标准错误 stderr 默认属于这一种类型,从而保证错误信息能够立即输出
    • _IOLBF:采用行缓冲 I/O。在这种情况下,当在输入或输出中遇到换行符"\n"时,标准 I/O 才会执行文件 I/O 操作。对于输出流,在输出一个换行符前将数据缓存(除非缓冲区已经被填满),当输出换行符时,再将这一行数据通过文件 I/O write()函数刷入到内核缓冲区中;对于输入流,每次读取一行数据。对于终端设备默认采用的就是行缓冲模式,譬如标准输入和标准输出
      #include<stdio.h>
      #include<stdlib.h>
      int main(void)
      {
      		printf("Hello World\n");  // 该程序运行起来只会打印Hello world, haha打印不出来
      		printf("haha");
      		for (;;)sleep(10);
      		return 0;
       }
      
    • _IOFBF:采用全缓冲 I/O。在这种情况下,在填满 stdio 缓冲区后才进行文件 I/O 操作(read、write)。对于输出流,当 fwrite 写入文件的数据填满缓冲区时,才调用 write()将 stdio 缓冲区中的数据刷入内核缓冲区;对于输入流,每次读取 stdio 缓冲区大小个字节数据。默认普通磁盘上的常规文件默认常用这种缓冲模式
  • setbuf(), setbuf()函数构建与 setvbuf()之上,执行类似的任务

    	#include <stdio.h>
      
      void setbuf(FILE *stream, char *buf);
      相当于 setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);(BUFSIZ 定义于头文件<stdio.h>中,该值通常为 8192
  • setbuffer(),

    	#include <stdio.h>
      void setbuffer(FILE *stream, char *buf, size_t size);
      相当于  setvbuf(stream, buf, buf ? _IOFBF : _IONBF, size);
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值