标准库IO编程

简介: 标准库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);


目录
相关文章
|
7月前
|
数据采集 异构计算
LabVIEW编程LabVIEW开发高级数据采集技术 操作数字IO 例程与相关资料
LabVIEW编程LabVIEW开发高级数据采集技术 操作数字IO 例程与相关资料
96 22
|
2月前
|
数据库
同步IO模型是一种常见的编程模型
【10月更文挑战第5天】同步IO模型是一种常见的编程模型
23 2
|
3月前
|
网络协议 Java Linux
高并发编程必备知识IO多路复用技术select,poll讲解
高并发编程必备知识IO多路复用技术select,poll讲解
|
4月前
|
Java 数据处理
Java IO 接口(Input)究竟隐藏着怎样的神秘用法?快来一探究竟,解锁高效编程新境界!
【8月更文挑战第22天】Java的输入输出(IO)操作至关重要,它支持从多种来源读取数据,如文件、网络等。常用输入流包括`FileInputStream`,适用于按字节读取文件;结合`BufferedInputStream`可提升读取效率。此外,通过`Socket`和相关输入流,还能实现网络数据读取。合理选用这些流能有效支持程序的数据处理需求。
51 2
|
4月前
|
小程序 Linux 开发者
Linux之缓冲区与C库IO函数简单模拟
通过上述编程实例,可以对Linux系统中缓冲区和C库IO函数如何提高文件读写效率有了一个基本的了解。开发者需要根据应用程序的具体需求来选择合适的IO策略。
37 0
|
5月前
|
缓存 网络协议 算法
【Linux系统编程】深入剖析:四大IO模型机制与应用(阻塞、非阻塞、多路复用、信号驱动IO 全解读)
在Linux环境下,主要存在四种IO模型,它们分别是阻塞IO(Blocking IO)、非阻塞IO(Non-blocking IO)、IO多路复用(I/O Multiplexing)和异步IO(Asynchronous IO)。下面我将逐一介绍这些模型的定义:
263 2
|
6月前
|
Java 数据库连接
提升编程效率的利器: 解析Google Guava库之IO工具类(九)
提升编程效率的利器: 解析Google Guava库之IO工具类(九)
|
7月前
|
存储 Java API
Java语言IO(输入/输出)编程技术深度解析
Java语言IO(输入/输出)编程技术深度解析
292 1
|
7月前
|
存储 编译器 vr&ar
【基础IO】谈谈动静态库(怒肝7000字)
【基础IO】谈谈动静态库(怒肝7000字)
|
6月前
|
调度 数据库 开发者
在Python编程中,并发编程和异步IO是两个重要的概念,它们对于提高程序性能和响应速度具有至关重要的作用
【6月更文挑战第10天】本文介绍了Python并发编程和异步IO,包括并发编程的基本概念如多线程、多进程和协程。线程和进程可通过threading及multiprocessing模块管理,但多线程受限于GIL。协程利用asyncio模块实现非阻塞IO,适合处理IO密集型任务。异步IO基于事件循环,能提高服务器并发处理能力,适用于网络编程和文件操作等场景。异步IO与多线程、多进程在不同任务中有各自优势,开发者应根据需求选择合适的技术。
48 0