分类:
2008-11-04 14:54:40
5.6 reading and writing a stream
分为formatted i/o以及unformatted i/o,其中unformatted又可以分为:
1.Character-at-a-time I/O. We can read or write one character at a time, with the standard I/O functions handling all the buffering, if the stream is buffered.
2.Line-at-a-time I/O. If we want to read or write a line at a time, we use fgets and fputs. Each line is terminated with a newline character, and we have to specify the maximum line length that we can handle when we call fgets.
3.Direct I/O. This type of I/O is supported by the fread and fwrite functions. For each I/O operation, we read or write some number of objects, where each object is of a specified size. These two functions are often used for binary files where we read or write a structure with each operation.
如下是character-at-a-time i/o:
#include int getc(FILE *fp); int fgetc(FILE *fp); int getchar(void); |
All three return: next character if OK, EOF on end of file or error |
Getc, fgetc都是从一个流读取一个字符,区别,getc有时候使用一个macro来定义的,而fgetc肯定就是一个函数,因此,其名字可以赋值给函数指针。
#include int ungetc(int c, FILE *fp); |
Returns: c if OK, EOF on error |
将一个字符退还给stream,注意退还的字符可以与当初读出来的不一样。而且所谓退还,其实并不将字符写回文件,而仅仅是放在了standard i/o 的buffer里面了。
#include int putc(int c, FILE *fp); int fputc(int c, FILE *fp); int putchar(int c); |
All three return: c if OK, EOF on error |
如下是line-at-a-time i/o:
#include char *fgets(char *restrict buf, int n, FILE *restrict fp); char *gets(char *buf); |
Both return: buf if OK, NULL on end of file or error |
Fgets提供了缓冲的大小,这样当缓冲长度不够容纳下一个串的时候,会仅仅将能够填满缓冲的数据返回,下次调用fgets会将后续的内容再加进来,是安全的。而gets,没有提供缓冲的大小参数,所以容易写越界。不建议使用。
#include int fputs(const char *restrict str, FILE *restrict fp); int puts(const char *str); |
Both return: non-negative value if OK, EOF on error |
Fputs的str内容并不一定一定以newline结尾,而且写到fp时,standard i/o也不会自动加newline。所以并不严格是line-at-a-time。
Puts就是严格的line-at-a-time,而且加入newline的工作由puts自己完成。
Standard i/o的output函数和底层的write函数最好不要混用,因为那样会造成undefined问题。根源是你一会儿使用standard i/o的缓冲,一会不用就乱了。读也是一样的。