- 读和写流
当流打开后,有3种非格式化I/O可对其进行读写操作:(1)每次一个字符,(2)每次一行的I/O,(3)直接I/O。
1、输入函数
#include<stdio.h>
//三个函数返回取到的字符,出错或到达文件尾返回EOF
int getc(FILE* fp); //可被实现为宏。
int fgetc(FILE* fp);
int getchar(void); // 等同于getc(stdin)。
返回int而不是unsigned char 是因为用int能够多返回一个EOF值(通常是-1)。
区别是到达文件尾还是出错,可用ferror或feof:
#include<stdio.h>
int ferror(FILE* fp);
int feof(FILE* fp);
void clearerr(FILE* fp); //清除错误标志
还可以利用函数ungetc将字符压回流中。
int ungetc(int c, FILE* fp);
成功返回压入的字符,错误反回EOF。类似于C++中的istream::putback(char ch)。同时ungetc会清除文件结束标志。
2、输出函数
#include<stdio.h>
int putc(int c, FILE* fp); //可被实现为宏
int fputc(int c, FILE* fp);
int putchar(int c); //三个函数成功返回输入的字符,出错返回EOF
- 每次一行I/O
#include<stdio.h>
//函数成功返回buf,出错或到达文件尾返回NULL。
char* fgets(char* restrict buf, int n, FILE* restrict fp); //从指定流读取n-1个,或者遇换行符结束
char* gets(char* buf); //从标准输入读,不推荐使用,可能造成溢出。换行符不存入缓冲区
char* fputs(const char* restrict str, FILE* restrict fp); //将一个以null字节终止的字符串写入指定流
char* puts(const char* str); //将一个以null字节终止的字符串写入标准输出,并补一个换行符
- 标准I/O效率
在对大量数据(98.5M,300万行)进行读写时,每次一行比每次一字节更慢(系统时间),这是由于每次一行除了需要本身的600万次函数调用外,还需要2亿次函数调用,而每次一行只需要2亿次函数调用。同时,标准I/O每次一字节要比BUFFSIZE=1的write/read要快得多,原因是write/read进行2亿次系统调用,而标准I/O只是2亿次函数调用加 2万多次系统调用。
- 二进制I/O
#include<stdio.h>
//两个函数返回读或写的对象数
size_t fread(void* restrict ptr, size_t size, size_t nobj, FILE* restrict fp);
size_t fwrite(const void* restrict ptr, size_t size, size_t nobj, FILE* restrict fp);
常用于数组和结构体。
二进制I/O只能用于同一系统上,因为:
(1)同一结构在不同系统上可能不同
(2)存储多字节整数和浮点数在不同系统下也可能不同
所以在不同系统上需要使用一些规范格式来交换数据。