C和指针(学习笔记)_第15章 输入/输出函数

1.错误报告

       perror函数以一种简单、统一的方式报告错误。标准库函数在一个外部整型变量errno(在errno.h中定义)中保存错误代码之后把这个信息传递给用户程序,提示操作失败的准确原因。perror函数简化向用户报告这些特点错误的过程。它的原型定义与stdio.h:

       void perror(char const *message)

       如果message不是NULL并且指向一个非空的字符串,perror函数就打印出这个字符串,后面跟一个分号和一个空格,然后打印出一条用于解释errno当前错误代码的信息。

注意:只有当一个库函数失败时,errno才会被设置,当函数运行成功时,errno的值不会被修改,这意味着不能通过测试errno的值来判断是否发生错误,反之,只有当被调用的函数提示有错误发生时检查errno的值才有意义。

2.终止执行

       exit函数用于终止一个程序的执行,它的原型定义于stdlib.h,函数定义为:void exit(int status); status参数返回给操作系统,用于提示程序是否正常完成。

3.标准I/O函数库

       标准I/O函数库具有一组I/O函数,实现了在原先的I/O库基础上许多程序员自行添加实现额外的功能;但这个函数存在两个主要的缺陷:1)是否对不同平台具有普适性,不同机器、不同平台、不同架构可能存在差异;2)正是1)中的原因,对程序的可移植性就会降低。

4.I/O概念

       1)流:所有I/O操作只是简单地从程序移进或移出字节,这种字节流便称为流。流分为两种类型,文本流和二进制流;

       2)文件:FILE是一种数据结构,用于访问一个流,运行时系统必须提供至少三个流:标准输入、标准输出、标准错误;

       3)标准I/O常量:EOF提示到达了文件尾。

5.流I/O总览

       1)程序为必须同时处于活动状态的每个文件声明一个指针变量,其类型为FILE *;

       2)流通过调用fopen函数打开;

       3)根据需要对该文件进行读取或写入;

       4)调用close函数关闭流。

       标准流的I/O更为简单,因为它们并不需要打开或关闭。

6.打开流

        FILE *fopen(char const *name,char const *mode);

            读取     写入    添加
 文本        “r”     "w"     "a"
二进制       "rb"    "wb"    "ab"

7.关闭流

       int fclose(FILE *f);

      是否应该对fclose(或任何其他操作)进行错误检查?首先问两个问题:1)如果操作成功应该执行什么?2)如果操作失败应该执行什么?若两个问题答案是不同的,那么你应该进行错误检查,相同时跳过错误检查才是合理的。

8.字符I/O

       字符输入由getchar函数家族执行,int fgetc(FILE *stream); int getc(FILE *stream); int getchar(void);

       单个字符写入到流中,可使用putchar函数家族,int fputc(int character,FIEL *stream); int putc(int character,FILE *stream);int putchar(int character);

      1)字符I/O宏:fgetc和fputc都是真正的函数,getc、putc、getchar和putchar都是通过#define指令定义的宏。

      2)撤销字符I/O:int ungetc(int character,FILE *stream);

9.未格式化的行I/O

char *fgetc(char *buffer,int buffer_size,FILE *stream);
char *gets(char *buffer);

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

10.格式化的行I/O

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

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

11.二进制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);

12.刷新和定位函数

int fflush(FILE *stream);

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

void rewind(FILE *stream);
int fgetpos(FILE *stream,fpos_t *position);
int fsetpos(FILE *stream,fpos_t const *position);

13.改变缓冲方式

void setbuf(FILE *stream,char *buf);
int setvbuf(FILE *stream,char *buf,int mode,size_t size);

14.流错误函数

int feof(FILE *stream);
int ferror(FILE *stream);
void clearerr(FILE *stream);

15.临时文件

FILE *tmpfile(void);

char *tmpnam(char *name);

16.文件操纵函数

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

17.总结

       FILE是一种数据结构,用于管理缓冲区和存储流的I/O状态;流用fopen函数打开,它的参数是需要打开的文件名和需要采用的流模式;逐字符的I/O由getchar和putchar函数家族实现;行I/O既可以格式化的,也可以是未格式化的;scanf和printf函数家族执行格式化的I/O操作;使用二进制流写入二进制数据比使用字符I/O效率更高;在缺省情况下,流是顺序读取的;在执行任何流操作之前,调用setbuf函数可以改变流所使用的缓存区;ferror和clearerr函数和流的错误状态有关;tmpfile函数返回一个与一个临时文件关联的流。

18.警告的总结

       1)忘了在一条调试用的printf语句后面跟一个fflush调用;

       2)不检查fopen函数的返回值;

       3)改变文件的位置将丢弃任何被退回到流的字符;

       4)在使用fgets时指定太小的缓存区;

       5)使用gets的输入溢出缓存区且未被检测到;

       6)在使用任何scanf系列函数时,格式代码和参数指针类型不匹配;

       7)在任何scanf系列函数的每个非数值、非指针参数前忘加上&符号;

       8)注意在使用scanf系列函数转换double、long double、short和long整型时,在格式代码中加入合适的限定符;

       9)sprintf函数的输出溢出了缓存区且未检测到;

      10)混淆printf和scanf格式代码;

      11)使用任何printf系列函数时,格式代码和参数类型不匹配;

      12)在有些长整数长于普通整型的机器上打印长整型数值时,忘了在格式代码中指定1修改字符;

      13)使用自动数值作为流的缓存区时应多加小心。

19.编程提示总结

      1)在可能出现错误的场合,检查并报告错误;

      2)操作文本行而无需顾及它们的外部表示形式这个能力有助于提高程序的可移植性;

      3)使用scanf限定符提高可移植性;

      4)当你打印整数时,即使你所用的机器并不需要,坚持使用1修改符可以提高可移植性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值