Linux 系统编程——标准I/O教程
目录
1. 缓冲
标准I/O提供缓冲的目的是为了尽量减少 read/write 的调用次数。
缓冲类型:
- 全缓冲:填满缓冲区之后才进行实际的I/O 操作;对磁盘文件通常使用全缓冲。
- 行缓冲:在输入输出中遇到换行符时就进行实际的I/O操作;对终端通常使用行缓冲。
- 无缓冲:就是没有缓冲区;标准错误通常使用无缓冲。
设置缓冲:
#include <stdio.h>
void setbuf(FILE *stream, char *buf);
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
成功时返回 0.
在打开流之后使用。
对于 setbuf,如果 buf 为 NULL 则关闭缓冲功能(无缓冲);否则 buf 的大小需为 BUFSIZ。
对于 setvbuf,mode 指定了缓冲类型:
_IOFBF
: 全缓冲;_IOLBF
: 行缓冲;_IONBF
: 无缓冲;忽略 buf(缓冲区) 和 size(buf 大小) 参数。
2. 打开流
#include <stdio.h>
FILE *fopen(const char *path, const char *mode);
FILE *freopen(const char *path, const char *mode, FILE *stream);
FILE *fdopen(int fd, const char *mode);
失败时返回 NULL.
mode 指定了打开的模式:r, rb, w, wb, a, ab, r+, rb+, w+, wb+, a+, ab+.
freopen 会在指定的流上以指定的模式打开,如果该流已打开,则先将其关闭。
获取流对应的文件描述符:
#include <stdio.h>
int fileno(FILE *stream);
返回该流相关联的文件描述符。
3. 关闭流
#include <stdio.h>
int fclose(FILE *stream);
成功时返回 0.
会在关闭之前刷新缓冲区中的输出数据,丢弃任何输入数据。
进程正常终止时,会刷新并关闭所有的标准I/O流。
4. 刷新流
#include <stdio.h>
int fflush(FILE *stream);
成功时返回 0.
使所有未写入的数据都传送到内核。
如果 stream 为 NULL,则刷新所有流。
5. 定位流
#include <stdio.h>
long ftell(FILE *stream);
成功时返回当前文件位置;失败时返回 -1.
int fseek(FILE *stream, long offset, int whence);
成功时返回 0;失败时返回 -1.
void rewind(FILE *stream);
int fgetpos(FILE *stream, fpos_t *pos);
int fsetpos(FILE *stream, const fpos_t *pos);
成功时返回 0;失败时返回非 0.
whence 取值:SEEK\_SET, SEEK\_CUR, SEEK\_END.
6. 格式化I/O
一次读一个字符
#include <stdio.h>
int getc(FILE *stream);
int fgetc(FILE *stream);
int getchar(void);
成功时返回下一个字符;失败时返回 EOF.
getchar 从 stdin 中读取输入。
getc 可被实现为宏。
可用如下函数来判断是到达 EOF 还是出错了:
#include <stdio.h>
int feof(FILE *stream);
int ferror(FILE *stream);
void clearerr(FILE *stream);
clearerr 用于清除错误标志和 eof 标志。
将字符压送回流中:
int ungetc(int c, FILE *stream);
成功时返回 0;失败时返回 EOF.
一次读一行
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
失败时返回 NULL.
读取一行放入 s (大小为 size)中,且保证 s 会以 NULL 结尾。
如果该行(包括换行符)的长度超过了 size-1,则返回一个不完整的行,下一次调用将继续读取该行。
会保留换行符。
一次写一个字符
#include <stdio.h>
int putc(int c, FILE *stream);
int fputc(int c, FILE *stream);
int putchar(int c);
成功时返回 c;失败时返回 EOF.
putc 可被实现为宏。
putchar 将字符写入 stdout.
一次写个字符串
#include <stdio.h>
int fputs(const char *s, FILE *stream);
成功时返回非负数;失败时返回 EOF.
格式化I/O
#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 *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, ...);
成功时返回输入的项数;失败或到达末尾时返回 EOF.
可变参数版本:
#include <stdarg.h>
int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vdprintf(int fd, 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);
7. 二进制I/O
#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);
返回读写的对象数。
读写 size 个对象,每个对象的大小均为 nmemb 字节。