1、标准I/O库-读写流调用fopen()成功打开流之后,可在三种不同类型的非格式化I/O中进行选择,对其进行读、写操作:每次一个字符的每次一个字符的I/O。使用fgetc()/fputc()一次读或写一个字符,如果流是带缓存的,则标准I/O函数处理所有缓存。每次一行的每次一行的I/O。使用fgets()和fputs()一次读或写一行。每行都以一个新行符终止。当调用fgets()时,应说明能处理的最大行长。直接直接I/O。fread()和fwrite()函数支持这种类型的I/O。每次I/O操作读或写某种数量的对象,而每个对象具有指定的长度。这两个函数常用于从二进制文件中读或写一个结构。标准I/O库
2、-读写流结束判定 feof()判断文件是否结束,可用于二进制文件。char cTemp;while(!feof(fp)&!ferror(stdin)cTemp=fgetc(fp);EOF/feof()EOF文件结束的返回标志,一般使用方法:char cTemp;cTemp=fgetc(fp);while(cTemp!=EOF)cTemp=fgetc(infile);标准I/O库-读写流-字符I/O-输入以下三个函数可用于一次读一个字符:三个函数的返回:若成功则为下一个字符,若已处文件尾端或出错则为EOF 函数getchar()等同于getc(stdin)注意,不管是出错还是到达文件尾端,这三个
3、函数都返回同样的值。为了区分这两种不同的情况,必须调用ferror()或feof()。getc()的实现是一个宏,而fgetc()是一个函数。返回值为int类型。标准I/O库-读写流-出错函数检查文件出错函数:检查文件出错函数:在大多数的FILE对象的实现中,保留两个标志:出错标志。文件结束标志。标准I/O库-读写流-字符I/O-输出以下三个函数可用于一次输出一个字符:putchar(c)等价于putc(c,stdout)。出错返回EOF。getc()/getchar()/putc()/putchar()实现为宏,fgetc()/fputc()实现为函数,请根据情况选择。标准I/O库-读写流-
4、字符I/O-exampleexample:循环从标准输入(stdin)逐个字符读入数据,并逐个字符显示到标准输出。输出结果:标准I/O库-读写流-行I/O-输入下列两个函数提供每次输入一行的功能:两个函数返回:若成功则为buf,若已处文件尾端或出错则为null 这两个函数都指定了缓存地址,读入的行将送入其中。gets()从标准输入读,而fgets()则从指定的流读。对于fgets(),必须指定缓存的长度n。此函数一直读到下一个新行符为止,但是不超过n-1个字符,读入的字符被送入缓存。该缓存以null字符结尾。如若该行,包括最后一个新行符的字符数超过n-1,则只返回一个不完整的行,而且缓存总是以
5、null字符结尾。对fgets()的下一次调用会继续读该行。gets()是一个不推荐使用的函数,因为调用者在使用gets()时不能指定缓存的长度,这样就可能造成缓存越界(如若该行长于缓存长度),写到缓存之后的存储空间中,从而产生不可预料的后果。gets()与fgets()的另一个区别是,gets()并不将新行符存入缓存中。标准I/O库-读写流-行I/O-输出下列两个函数提供每次输出一行的功能:两个函数返回:若成功则为非负值,若出错则为EOF 函数fputs()将一个以null符终止的字符串写到指定的流,终止符null不写出。注意,这并不一定是每次输出一行,因为它并不要求在null符之前一定是新
6、行符。通常,在null符之前是一个新行符,但并不要求总是如此。puts()将一个以null符终止的字符串写到标准输出,终止符不写出。但是,puts()然后又将一个新行符写到标准输出。puts()并不像它所对应的gets()那样不安全。但是我们还是应避免使用它,以免需要记住它在最后又加上了一个新行符。如果总是使用fgets()和fputs(),那么就会熟知在每行终止处我们必须自己加一个新行符。标准I/O库-读写流-行I/O-example输出结果:example:循环从标准输入(stdin)逐行读入数据,并逐行字符显示到标准输出,每次读取的最大长度为20字节。标准I/O库-读写流-二进制I/O下
7、列两个函数以执行二进制I/O(direct I/O)操作:两个函数的返回:读或写的对象数 对于二进制数据我们更愿意一次读或写整个结构。为了使用getc()或putc()做到这一点,必须循环读取整个结构,一次读或写一个字节。(效率低)fputs()在遇到null字节时就停止,而在结构中可能含有null字节,所以不能使用每次一行函数实现这种要求。如果输入数据中包含有null字节或换行符,则fgets()也不能正确工作。(实现限制)标准I/O库-读写流-二进制I/O-exampleexample1:读或写一个二进制数组,将一个浮点数组的第2至第5个元素写至一个文件上:标准I/O库-读写流-二进制I/
8、O-exampleexample2:读或写一个结构体,将一个结构体写至一个文件上:标准I/O 效率 fgets()/fputs()/getc/putc调用代码标准I/O 效率 fgets()/fputs()/getc/putc 效率对比图标准I/O库-定位流定位标准I/O流的两种方式 ftell()和fseek():这两个函数自V7以来就存在了,但是它们都假定文件的位置可以存放在一个长整型中。fgetpos()和fsetpos()。这两个函数是新由ANSI C引入的。它们引进了一个新的抽象数据类型fpos_t,它记录文件的位置。需要移植到非UNIX系统上运行的应用程序应当使用fgetpos()
9、和fsetpos()标准I/O库-定位流-fseek()/ftell()/rewind()fseek()/ftell()/rewind()函数原型:ftell()用于取得当前的文件位置,调用成功则为当前文件位置指示,若出错则为-1L fseek()用户设定stream流的文件位置指示,调用成功返回0,失败返回-1,并设置errno fseek()的whence参数:SEEK_SET/SEEK_CUR/SEEK_END。rewind()用于设定流的文件位置指示为文件开始,该函数调用成功无返回值。rewind()等价于(void)fseek(stream,0L,SEEK_SET)标准I/O库-定位
10、流-fgetpos()/fsetpos()两个函数返回:若成功则为0,若出错则为非0 fgetpos()将文件位置指示器的当前值存入由pos指向的对象中。在以后调用fsetpos()时,可以使用此值将流重新定位至该位置。需要移植的程序,应该优先考虑fgetpos()/fsetpos()。fgetpos()/fsetpos()函数原型:标准I/O库-临时文件标准I/O库提供了两个函数以帮助创建临时文件:tmpnam()产生一个与现在文件名不同的一个有效路径名字符串。每次调用它时,它都产生一个不同的路径名。tmpnam()的s如果为NULL,则返回值存放到一个静态的区中。如果s不为NULL,则认为
11、其指向长度至少为L_tmpnam个数的字符数组中。所产生的文件名存放到该数组中,也作为函数返回值返回。tmpfile()创建一个临时二进制文件(类型wb+),在关闭该文件或程序结束时将自动删除这种文件。标准I/O库-临时文件example 自己实现一个tmpfile()函数。先调用tmpnam()产生一个唯一的路径名。调用fopen()打开。调用unlink()删除。说明:Linux系统规定,一个文件如果有连接计数器不为0,或者其进程打开数不为0,均不会删除其文件内容,利用这个特点来实现tmpfile()。I/O模型比较I/O模型文件I/O标准I/O缓冲方式非缓冲I/O缓冲I/O操作对象文件描述符流(FILE*)打开open()fopen()/freopen()/fdopen()读read()fread()/fgetc()/fgets()写write()fwrite()/fputc()/fputs()定位lseek()fseek()/ftell()/rewind()/fsetpos()/fgetpos()关闭close()fclose()