Apue stand io 读书笔记
缓冲
1:fully buffer
2:line buffer
3:unbuffered
Reading and writing a stream
1: charactor-at-a-time IO
Getc:
Fgetc:
Getchar():
Getc(stdin) = getchar()
NOTES: note that these functions return the same value whether an error occurs or the end of file is reached. To distinguish between the two ,
we must call either ferror or feof
Putc ,fputc , putchar(c)
2: line-at-a-time IO
Fgets(char * restrict buf,int n, FILE * restrict fp):
Fgets 读取最多n-1 个字符(包括换行符),最后一个字符以null 结束
Char * gets(char * buf):
Gets(buf) 从标准输入读数据,尽量少用,因为不知道buffer 长度,并且gets 并不像fgets那样讲newline 也保持到buffer 里面。
Fputs:fputs writes the null-terminated string to the specified stream , the null byte at the end is not written , 通常最后一个字节都是newline,但是不保证是
Puts: 输出到标准输出,其他和上面一样,但是呢保证最后一个字节是newline
总结: 上面四个函数, fputs 和fgets 主要是newline的困惑,因为在特定情况下不会传输newline, 所以需要程序判断处理newline,
gets和puts呢因为buffer 长度不确定的原因,很容易造成问题,所以尽量少用。
3:Direct IO(structure-oriented IO)
为什么有direct IO 呢?通过上面讲解, 我们知道 遇到newline ,null byes ,上面的函数就会返回, 当我们需要读入一个结构体什么的,
这个结构体内容当然可以为null byte。
Fread(buf,size,num,fp)
Fwrite(buf, size,num,fp)
有以下两种应用场景:
1: 读写一个二进制的数组
Float data[10];
If(fwrite(&data[2],sizeof(float),4,fp) != 4)
2: 读写一个结构体
Struct {
Short count; long total;
}item;
Fwrite(&item,sizeof(item),1,fp)
对于读(fread) 返回值为读的元素个数,可能小于我们期待的值,这时候用ferror 或者feof来判断是错误还是文件结束
对于fread 和fwrite的问题是最好在同一个系统中调用,不能够保证在异构的系统中同样起作用,因为在不同的系统中,
同样的结构体内部成员的offset可能不一样, 大小端顺序也可能不一样。 所以在不同的机器上面传输二进制数据时需要特别注意
下面补充一点:
对于flush 操作
在unix环境中,flush有两种意思:
1) 标准I/0 库,将缓冲区内容写到磁盘上面
2) 终端驱动程序: 丢弃已存储在缓冲区中的数据
要特别留意stdin stdout 在具体的语境中是行缓冲还是全缓冲