读《C和指针》笔记摘要【6】

来源:互联网 发布:淘宝收藏认准淘行者 编辑:程序博客网 时间:2024/05/06 01:30

2010-04-09


第十五章    输入/输出函数


1、错误报告

perror函数     void perror( char const *message);


2、终止执行

void exit( int status );    原型定义于stdlib.h

其中status参数返回给操作系统,用于提示程序是否正常完成,这个值和main函数返回的整型状态值相同,预定义符号EXIT_SUCESS和EXIT_FAILURE分别提示程序的终止是成功还是失败;


3、对C语言而言,所有的I/O操作知识简单地从程序移进或移出字节的事情,毫不惊奇的是,这种字节流便称为流,程序只关心创建正确的输出字节数据,以及正确的解释从输入读取的字节数据,特定I/O设备的细节对程序员是隐藏的;


4、绝大多数是完全缓冲的,这就意味着“读取”和“写入”实际上时从一块称为缓冲区德内存区域来回复制数据;


5、在进行程序调试时,在每个调试的printf函数之后立即调用fflush函数,迫使缓冲区的数据立即写入,不管它是否已满;

例如:printf( "something or other" );

fflush( stdout );


6、文本流

流分为文本流和二进制流两种,文本流的有些特性可能因系统不同而不同;


7、标准C程序运行时至少提供三种流——标准输入,标准输出,标准出错,即:stdin, stdout, stderr;他们都是只想一个FILE结构的指针;


8、标准I/O常量

EOF所选择的实际值比一个字符要多几位,这是为了避免二进制值被错误地解释为EOF;


9、打开流

r, w, 和 a 开头,分别表示打开的流用于读取,写入还是添加;如果以读方式打开,则文件必须存在,而其余的方式文件可存在,可不存在,不存在将创建;


10、如果在mode中添加“a+”这种方式的话,表示该文件打开用于更新,但当你已经从该文件读入了一些数据,如果你要开始向他写入数据时,你必须先调用其中一个文件定位函数(fseek, fsetpos, rewind),在你向文件写入数据后,你又想读的话,那么又要调用fflush或文件定位函数之一;


11、freopen函数用于打开(或重新打开)一个特定的文件流

FILE * freopen( char const *filename, char const *mode, FILE *stream );


12、关闭流

fclose函数,对于输入流,fclose函数在文件关闭之前刷新缓冲区,如果它执行成功,fclose返回零值,否则返回EOF;


13、字符I/O

① int fgetc( FILE *stream );

② int getc( FILE *stream );

③ int getchar( );

这些都用于读取字符,但他们都返回一个int型值而不是char型值,因为EOF比字符多几位,这样是为了报告成功到达文件尾的保证;

① int fputc( int character, FILE *stream );

② int putc( int character, FILE *stream );

③ int putchar( int character );

putchar( 'abc' );  这句话只打印其中一个(这个由编译器决定)

上述函数如果写入失败,则返回EOF;


14、字符I/O宏

fgetc 和 fputc是真正的函数,但getc,putc,getchar和putchar都是通过#define指令定义的宏;


15、撤销字符I/O

ungetc函数:int ungetc( int character, FILE *stream );


16、未格式化的行I/O

① char *fgets( char *buffer, int buffer_size, FILE*stream );

② char *gets( char *buffer );

A. int fputs( char const *buffer, FILE *stream );

B. int puts( char const *buffer );

解析:fgets从指定的stream读取字符并复制到buffer中,当它读取一个换行符并存储到缓冲区之后就不在读取,如果缓冲区存储的字符到达了buffer_size - 1时他就停止读取,在这种情况下,不会出现数据丢失的情况,因为下一次调用fgets将从流的下一个字符开始读取,在任何一种情况下,一个NUL字节将被添加到缓冲区所存储数据的末尾,使它成为一个字符串;


fputs的缓冲区必须保护一个字符串,它的字符被写入到流中,这个字符串预期以NUL结尾,所以这个函数没有一个缓冲区长度参数,这个字符串是逐字写入的,如果它不包含一个换行符,就不会写入换行符,如果它包含多个,则会全部写入,因此,当fgets每次都读取整行时,可以一次写入好几行,如果写入失败,返回EOF,否则非负值;


gets和puts函数几乎和fgets与fputs相同,之所以存在他们是为了允许向后兼容,他们之间的一个主要功能区别在于当gets读取一行输入时,他并不在缓冲区中存储结尾的换行符,当puts写入一个字符串时,它在字符串写入之后向输出再添加一个换行符;


17、格式化的行I/O

① scanf家族:

int fscanf( FILE *stream, char const *format, ...);

int scanf( char const *format, ...);

int sscanf( char const *string. char const *format, ... );

②printf家族:

int fprintf(FILE *stream, char const *format, ... );

int printf( char const *format, ...);

int sprintf( char *buffer, char const *format, ... );


printf函数可以使用丰富的格式代码,修改符,限定符,替代形式和可选字段,这使得它看上去极为复杂,但是他们能够在格式化输出时提供极大的灵活性,所以,你应该耐心一些,把他们学会要花一些时间;

sprintf函数把他的结果作为一个NUL结尾的字符串存储到指定的buffer缓冲区,而不是写入到流中,返回实际写入或打印的字符数;


18、二进制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 );


19、刷新与定位函数

int fflush(FILE *stream);

定位:long ftell( FILE *stream ); 函数返回流的当前位置,也就是一个距离文件开头的一个偏移量;

int fseek( FILE *stream, long offset, int from );

此函数的后两个参数中,在二进制中,从SEEK_END进行定位可能不被支持,所以应该避免,在文本六种,如果from是SEEK_CUR或者SEEK_END,offset必须是零,如果from是SEEK_SET,offset必须是一个从同一个流中以前调用过ftell所返回的值;


20、流错误函数

int feof( FILE *stream );

int ferror( FILE *stream );

void clearerr( FILE *stream );

如果处于文件尾,feof为真, 出现任何错误ferror为真,clearerr为指定流的错误标志进行重置;


21、文件操纵函数

int remove( char const *filename );//

int rename( char const *oldname, char const *newname );


原创粉丝点击