/*
读书笔记类型多种多样,有摘抄型的,有感想型的,有批注型的,有摘要型的……
现在正在研读《C和指针》,其中有很多我认为必要的知识点,摘抄并简单整理了一下,记录在这里。
*/
80. 当一个流被打开后,它可以用于输入和输出,最简单的形式是字符I/O,字符输入由getchar函数家族执行,它的原型如下:
int fgetc( FILE *stream );
int getc( FILE *stream );
int getchar( void );
需要操作的流作为参数传递给getc和fgetc,但getchar始终从标准输入读取。每个函数从流中读取下一个字符,并把它作为函数返回值返回。如果流中不存在更多的字符,函数就返回常量值EOF. 返回int型值的真正原因是为了允许函数报告文件的末尾EOF.
把单个字符写入流中,要使用putchar函数家族。
int fputc( int character, FILE *stream );
int putc( int character, FILE *stream );
int putchar( int character );
第1个参数是要被打印的字符,如果由于任何原因(如写入到一个已被关闭的流)导致函数失败,它们就返回EOF.
81. fgetc和fputc是真正的函数,而getc、putc、getchar和putchar都是宏。
82. ungetc函数
int unget( int character, FILE *stream );
ungetc把一个先前读入的字符返回到流中,以便它以后被重新读入。每个流都允许至少一个字符被退回。如果一个流允许退回多个字符,这些字符再次被读取的顺序就以退回时的反序进行。注意把字符退回到流中和写入到流中并不相同。与一个流相关的外部存储并不受ungetc影响。
退回字符和流的当前位置有关,所以如果用fseek、fsetpos或rewind函数改变了流的位置,所有退回的字符都将被丢弃。
83. 行I/O可以用两种方式执行——未格式化的或格式化的。两种形式都用于操纵字符串。区别在于未格式化的I/O(unformatted line I/O)简单读取或写入字符串,而格式化的I/O则执行数字和其他变量的内部和外部表示形式之间的转换。
84. 未格式化的行I/O
gets函数家族
char *fgets( char *buffer, int buffer_size, FILE *steam );
char *gets( char *buffer );
fgets函数从指定的stream读取字符并把它们复制到buffer中,当它读取一个换行符并存储到缓冲区之后就不再复制。如果缓冲区内存储的字符达到buffer_size – 1个时它也停止读取。这种情况下,并不会出现数据丢失的情况,再次调用fgets函数时将从流的下一个字符开始读取。任何一种情况下,一个NULL字节将被添加到缓冲区所存储数据的末尾,使它成为一个字符串。
如果在任何字符读取前就到达了文件尾,缓冲区就未进行修改,fgets函数返回一个NULL指针。否则,fgets返回它的第1个参数(指向缓冲区的指针)。
puts函数家族
int fputs( char const *buffer, FILE *stream );
int puts( char const *buffer);
传递给fputs的缓冲区必须包含一个字符串,它的字符被写入到流中,这个字符串预期以NUL字节结尾,所以该函数没有一个缓冲区长度参数。
gets和puts函数几乎与fgets和fputs相同,之所以存在它们是为了允许向后兼容。主要区别是当gets读取一行输入时,它并不在缓冲区存储结尾的换行符;当puts写入一个字符串时,它在字符串写入之后再添加一个换行符。另一个区别是gets函数没有缓冲区长度参数。
85. 格式化行I/O
scanf函数家族
int fscanf( FILE *stream, char const *format, … );
int scanf( char const *format, … );
int sscanf( char const *string, char const *format, … );
fscanf接受一个流参数,scanf从标准输入读取,sscanf从一个内存中的缓冲区接收字符。scanf家族的函数根据一个格式字符串对字符进行转换,一个指针参数列表用于提示结果值的存储地点,函数的返回值是被转换的值的个数,如果没有任何值被转换就遇到文件尾,函数就返回EOF.
printf函数家族
int fprintf( FILE *stream, char const *format, … );
int printf( char const *format, … );
int sprint( char *buffer, char const *format, … );
printf家族的三个函数的属性与scanf家族类似,printf家族的函数根据一个格式字符串转换为字符形式,这些值是作为参数传递给函数的。
/*
scanf和printf函数的参数有很多。记得当年教科书上有一大堆,而且考试以及后来二级C语言考试都会考一些。但这些就不记录在这里了,实际用到了再去查吧。
*/
86. 二进制I/O函数
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
size_t fwrite( void *buffer, size_t size, size_t count, FILE *stream );
buffer是指向用于保存数据的内存位置指针,size是缓冲区每个元素的字节数,count是读取或写入的元素数,stream为数据读取或写入的流。
87. 流定位函数
long ftell( FILE *stream );
int fseek( FILE *stream, long offset, int from );
ftell返回流当前位置,即下一个读取或写入将要开始的位置距离文件起始位置的偏移量。fseek用于在流中定位,它是一个偏移量,参考位置可以是起始位置或当前位置或结尾位置。
void rewind( FILE *stream );
int fgetpos( FILE *stream, fpos_t *position );
int fsetpos( FILE *stream, fpos_t *position );
rewind函数将读/写指针设置回指定流的起始位置,同时清除流的错误提示标志。fgetpos和fsetpos分别是ftell和fseek的替代方案,这对函数接受一个指向fpos_t的指针作为参数,fgetpos在这个位置存储文件的当前位置,fsetpos把存储在这个位置的值设置为文件位置。
88. 流缓冲方式函数
void setbuf( FILE *stream, char *buf );
int setvbuf( FILE *stream, char *buf, int mode, size_t size );
在任何流操作之前,调用setbuf函数可以改变流所用的缓冲区。用这种方式可以防止系统为流动态分配一个缓冲区。向这个函数传递NULL参数,表示禁止使用缓冲区。setvbuf可以指定非标准长度的缓冲区,也可以选择缓冲方式:全缓冲、行缓冲或不缓冲。
89. 流错误函数
int feof( FILE *stream );
int ferror( FILE * stream );
void clearerr( FILE *stream );
如果流当前处于文件尾,feof返回真,该状态可以通过对流执行fseek、rewind或fsetpos函数来清除。ferror报告流的错误状态,出现任何读/写错误就返回真。clearerr函数对指定流的错误标志进行重置。
90. 临时文件
FILE *temfile( void );
建立一个临时文件,当文件被关闭或程序终止时,文件便自动删除。
char *tmpname( char *name );
为临时文件创建文件名。
91. 文件操作函数
int remove( char const *filename );
int rename( char const *oldname, char const *newname );
remove函数删除一个指定文件,rename函数改变一个文件的名字。
/*
最近连接三篇都是整理的第15章《输入/输出函数》的内容。基本都是以大段的摘抄为主。当年学这部分的时候,老师几乎没怎么讲,当然我也没怎么学,后来呢,也没怎么用上。但总觉得有一部分知识空缺在这里很别扭,所以这部分花了比较长的时间和篇幅来做了整理和记录。
*/
用户593939 2014-10-21 23:01
用户1733654 2014-10-18 09:30