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


目录
相关文章
|
2月前
|
测试技术 C++ iOS开发
c++IO库详细介绍
前言 简单分享一下c++ IO相关的一些知识点,希望对大家有用
49 0
|
4月前
|
Linux 编译器 vr&ar
Linux基础IO【软硬链接与动静态库】
Linux基础IO【软硬链接与动静态库】
45 1
|
5月前
|
Linux 测试技术 API
linux系统编程 文件io
linux系统编程 文件io
113 0
|
6月前
|
数据采集 并行计算 Java
【文末送书】Python高并发编程:探索异步IO和多线程并发
【文末送书】Python高并发编程:探索异步IO和多线程并发
128 0
|
1天前
|
人工智能 算法 调度
uvloop,一个强大的 Python 异步IO编程库!
uvloop,一个强大的 Python 异步IO编程库!
10 2
|
2天前
|
API 调度 开发者
Python中的并发编程:使用asyncio库实现异步IO
传统的Python编程模式中,使用多线程或多进程实现并发操作可能存在性能瓶颈和复杂性问题。而随着Python 3.5引入的asyncio库,开发者可以利用异步IO来更高效地处理并发任务。本文将介绍如何利用asyncio库实现异步IO,提升Python程序的并发性能。
|
4月前
io_uring之liburing库安装
io_uring之liburing库安装
210 0
|
1月前
|
调度 数据库 Python
Python中的并发编程:使用asyncio库实现异步IO
传统的Python程序在面对IO密集型任务时,往往会遇到性能瓶颈。本文将介绍如何利用Python中的asyncio库,通过异步IO的方式来提升程序的效率和性能,让你的Python程序能够更好地处理并发任务。
|
2月前
|
大数据 程序员 Python
Python中的异步编程:使用asyncio库实现高效IO操作
传统的同步编程模式在处理IO密集型任务时效率较低,因此异步编程成为了解决这一问题的关键。本文将介绍如何利用Python中的asyncio库实现异步编程,以及如何利用异步特性提高IO操作的效率,让你的程序更加响应迅速。
|
2月前
|
存储 Rust 安全
Rust标准库概览:集合、IO、时间与更多
本文将带领读者深入了解Rust标准库中的一些核心模块,包括集合类型、输入/输出处理、时间日期功能等。我们将通过实例和解释,探讨这些模块如何使Rust成为高效且安全的系统编程语言。