Linux系统的文件IO都是针对文件描述符的,而标准IO(ISO C)的操作则是围绕流进行的,一个最明显的区别是标准IO比Linux文件IO多了缓冲机制。为了使用流,需要用到文件指针即指向FILE结构的指针,在“libio.h”头文件中有FILE结构的详细说明。“stdio.h”头文件中定义了三个标准流,stdin、stdout和stderr,分别是标准输入、标准输出和标准出错。流可以分为非格式化IO和格式化IO,前者又分为字符IO、行IO和二进制IO,后者如常见的scanf、printf函数等。对于ASCII字符集,有的字符用一个字节(单字节)表示,有的字符用多个字节(宽字节)表示,当一个流最初被创建时,它并没有定向,若在未定向的流上使用一个多字节IO函数,则将该流的定向设置为宽定向,若在未定向的流上使用一个单字节IO函数,则将该流的定向设置为字节定向,更改流定向只有两个函数,freopen和fwide,freopen用以清除流定向,fwide用于设置流定向。

#include <stdio.h>
FILE *freopen(const char *path, const char *mode, FILE *stream);
#include <wchar.h>
int fwide(FILE *stream, int mode);

缓冲——

标准IO提供缓冲的目的是尽可能地减少read和write系统调用的次数,它对每个IO流自动地进行缓冲管理,从而避免了应用程序需要考虑这一点所带来的麻烦。标准IO提供了三种类型的缓冲,全缓冲、行缓冲和无缓冲。全缓冲在填满标准IO缓冲区后才进行实际IO操作;行缓冲在输入和输出中遇到换行符或行缓冲区填满时执行IO操作;无缓冲即标准IO不对字符进行缓冲存储。一般清空下,有默认的缓冲方式,标准出错流stderr不带缓冲,从而使得出错信息可以尽快显示出来,涉及终端设备时流是行缓冲的,其它情况是全缓冲的,更改缓冲方式可通过setbuf和setvbuf函数完成,setvbuf可以指定具体的缓冲方式(mode),在“stdio.h”头文件中有一个适合系统的缓冲区长度宏定义BUFSIZ。

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

调用fflush函数可强制冲洗一个流或所有输出流:

#include <stdio.h>
int fflush(FILE *stream);

当一个进程正常终止时,即调用exit函数或者从main函数返回,那么所有未写的带缓冲数据的标准IO流都会被冲洗,所有打开的标准IO流都会被关闭。

打开与关闭流——

#include <stdio.h>
FILE* fopen(const char *path, const char *mode);
FILE* fdopen(int fd, const char *mode);
FILE* freopen(const char *path, const char *mode, FILE *stream);
int fclose(FILE *fp);

上面前三个函数可以打开一个标准IO流,fopen打开指定的文件,freopen在预定义的流(一般为stdin/stdout/stderr)上打开指定的文件,fdopen使得流关联到一个文件描述符上。fclose函数用以关闭一个打开的流。

流状态——

下面三个函数用于检查、设置流的状态,如EOF标志(一般为-1)、错误标志。

#include <stdio.h>
int ferror(FILE *stream);
int feof(FILE *stream);
void clearerr(FILE *stream);

流定位——

下面列出的是用于流定位的几个函数,它们基于不同的标准。

#include <stdio.h>
int ftell(FILE *stream);
int fseek(FILE *stream, long offset, int whence);
void rewind(FILE *stream);
int fgetpos(FILE *stream, fpos_t *pos);
int fsetpos(FILE *stream, fpos_t *pos);
off_t ftello(FILE *stream);
int fseeko(FILE *stream, off_t offset, int whence);

字符IO——

#include <stdio.h>
int getc(FILE *stream);
int fgetc(FILE *stream);
int getchar(void);
int ungetc(int c, FILE *stream);
int putc(int c, FILE *stream);
int fputc(int c, FILE *stream);
int putchar(int c);

在上面的字符IO中,前三个get系列函数用于一次读取一个字符,其中getchar等效于getc(stdin),getc可实现为宏而fgetc不能,这意味着getc的参数不能是有副作用的表达式,fgetc的函数地址看作为参数传递,fgetc耗时可能比getc要长。ungetc函数用于把字符压送会流中,后面三个put系列函数则用于一次输入一个字符。

行IO——

#include <stdio.h>
char* gets(char *s);
char* fgets(char *s, int size, FILE *stream);
int puts(const char *s);
int fputs(const char *s, FILE *stream);

在上面的行IO中,get系列函数用于一次读取一行,put系列函数用于一次输入一行,需要注意的是gets由于未指定行的长度,有可能造成缓冲区溢出,这几个函数的行尾换行符也要注意。

二进制IO——

#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);

上面的两个二进制IO在处理复杂的数据结构时,如果在不同的机器上执行,可能会有问题,如编译方式、字节对齐等问题。

格式IO——

下面列出的是常见的格式化输入、输出IO。

#include <stdio.h>
int printf(const char *format, …);
int fprintf(FILE *stream, const char *format, ...);
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);
int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);
#include <stdarg.h>
int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
int vscanf(const char *format, va_list ap);
int vsscanf(const char *str, const char *format, va_list ap);
int vfscanf(FILE *stream, const char *format, va_list ap);

printf系列函数的format中,需要进行格式控制时由百分号开始,其余字符则原样输出。格式控制形式如下:

%[flag][width][precision][modifier]type

flag可选,“-”表示左对齐,默认右对齐,“+”表示输出正负号,默认正数和零不输出,“ ”即空格,表示不带正负号时在前面添加空格,默认不添加,“#”表示添加进制符号,如十六进制的0x,默认不添加,“0”表示填充数字零,默认使用空格填充。

width表示输出的字符宽度,是一个十进制数,或是一个星号“*”,星号的意思是具体宽度由后面的参数给出。

precision表示精度,对于整型来说表示最少输出位数,对于浮点型来说表示小数点后的最少位数,对于字符串来说表示最多输出位数,precision以小数点开始,后接一个十进制整数或者星号“*”。

modifier表示参数长度,如下:

type表示参数类型,如下:

临时文件——

标准IO库还提供了用于创建临时文件的若干函数,tmpnam、tempnam、mktemp用以构建临时文件名,tmpfile、mkstemp用于创建临时文件。

#include <stdio.h>
FILE *tmpfile(void);
char *tmpnam(char *s);
char *tempnam(const char *dir, const char *pfx);
#include <stdlib.h>
int mktemp(char *template);
int mkstemp(char *template);

标准IO不足——

标准IO库的一个不足之处是效率不高,这与它需要复制的数据量有关。当使用每次一行函数fgets和fputs时,通常需要复制两次数据:一次是在内核和标准IO缓冲之间(当调用read和write时),第二次是在标准IO缓冲区和用户程序中的行缓冲区之间。而快速IO库则避免了这一点,其方法是使读一行的函数返回指向该行的指针,而不是将该行复制到另一个缓冲区。

【Linux】标准IO库相关推荐

  1. Linux操作与管理文件(多次打开同一文件,文件共享,fcntl函数,标准IO库)

    1.linux系统如何管理文件 硬盘中的静态文件和inode: (1)硬盘分为两大区域:一个是硬盘内容管理表项,另一个是真正存储内容的区域.先去读取硬盘内容管理表,找到要访问的存储内容的区域,再用得到 ...

  2. Linux后台开发系列之「13.标准 IO 库」

    StdIO.png 版权声明:本文为 cdeveloper 原创文章,可以随意转载,但必须在明确位置注明出处! 标准 IO 库 上一篇文章我们学习了 5 个底层的 IO 函数,这次我们来学习标准的 I ...

  3. Linux操作系统-标准IO库(2)

    Linux操作系统-标准IO库(2)(2015-8-4) 分类:Linux操作系统   打开一个流后,可采用三种不同类型的非格式化I/O对其进行读,写操作. 1. 每次读取一个字符的I/O 2. 每次 ...

  4. Linux操作系统-标准IO库(3)

    Linux操作系统-标准IO库(3)(2015-8-5) 分类:Linux操作系统 二进制IO和定位流   二进制I/O也称直接I/O,一个一个对象的I/O,面向记录的I/O或面向结构的I/O.每次I ...

  5. 标准IO库--unix环境高级编程读书笔记

    标准IO库是C语言提供的一个库,不光存在于linux中,在windows中也是有的.标准IO库和文件IO的不同是,标准IO库是对文件IO(即系统调用)的封装,并且在用户层添加了一些缓冲区. 文件IO的 ...

  6. C++ Primer 第八章 标准IO库

    学习本章内容之前有必要对缓冲区的概念做一个基本了解,我引用了网上一片文章<C++编程对缓冲区的理解>,内容如下: 什么是缓冲区    缓冲区又称为缓存,它是内存空间的一部分.也就是说,在内 ...

  7. C++ Primer 第八章 标准IO库(转载)

    学习本章内容之前有必要对缓冲区的概念做一个基本了解,我引用了网上一片文章<C++编程对缓冲区的理解>,内容如下: 什么是缓冲区    缓冲区又称为缓存,它是内存空间的一部分.也就是说,在内 ...

  8. 在标准IO库中,rewind函数作用?

    在标准IO库中,rewind函数作用? 将文件内部的位置指针重新指向一个流(数据流/文件)的开头 一个完整的信号生命周期包含4个重要的事件,这4个重要事件分别是? 信号诞生:信号在进程中注册完毕:信号 ...

  9. 《UNIX环境高级编程》笔记 第五章-标准IO库

    1. 流和FILE对象 在第三章的系统调用都是围绕文件描述符fd的.但是标准I/O库函数操作则是围绕流进行的.当使用标准I/O库打开或创建一个文件时,使用一个流与一个文件关联. 当打开一个流时,标准I ...

最新文章

  1. 【数论】【Polya定理】【枚举约数】【欧拉函数】【Java】poj2154 Color
  2. pytorch 忽略层权重
  3. jQuery - 获取并设置 CSS 类
  4. 在vscode上编写jsp_使用vscode高效编写博客园博客
  5. [20150629]12c物化视图刷新Out of place
  6. maven 打包javadoc乱码解决方案
  7. linux的cimserver是什么服务,openpegasus的启动方式(即cimserver的启动方式)
  8. vb怎么调用oracle数据库连接,VB 连接Oracle数据库
  9. 较低成本的ISO7637-2 5A 5B抛负载保护方案
  10. 莫让“浮云”遮望眼:“企业技术”才是硬道理
  11. 移动开发需要了解的UI设计知识
  12. excel从身份证号码中获取邮编信息?
  13. html+css取消下划线
  14. 牛根生:我们应该学会“三换思维”
  15. Oracle字段保留2两位小数点number类型
  16. 如何撰写综述性科技论文(网摘)
  17. vscode 如何设置保存后自动格式化【在设置中搜索formatOnSave设置启用】
  18. WHQL认证公司 提供高品质whql认证服务
  19. Android 多线程实现方式
  20. 小白怎样学习数据分析?

热门文章

  1. jquery实现仿select列表的即时搜索及拼音搜索
  2. 平分肥宅快乐水之辗转相除法
  3. 通过将FVCOM与水生生物地球化学模型框架(FABM)结合使用
  4. 【已解决】nginx 502 Bad Gateway 问题排查
  5. VB与 VC之间的差别
  6. 07年美科技股涨幅排行榜 百度第一
  7. 蓝牙技术|蓝牙BLE在可穿戴设备上的应用
  8. 水仙花数(3位水仙花、100-999之内的所有水仙花、三位及以上水仙花)
  9. 说说国产电影,烂片赚大钱时代来临
  10. 开启合同签署新方式!百度超级链推出区块链智能签约服务