I/O函数
索引:
- clearerr
- fclose
- feof
- ferror
- fflush
- fgetc
- fgetpos
- fgets
- fopen
- fprintf
- fputc
- fputs
- fread
- freopen
- fscanf
- fseek
- fsetpos
- ftell
- fwrite
- getc
- getchar
- gets
- perror
- printf
- putc
- putchar
- puts
- remove
- rename
- rewind
- scanf
- setbuf
- setvbuf
- snprintf
- sprintf
- sscanf
- tmpfile
- tmpnam
- ungetc
- vprintf、vfprintf、vsprintf、vsnprintf
- vscanf、vfscanf、vsscanf
与I/O相关的头文件是stdio.h,它定义了文件系统使用的宏和类型。最重要的类型是文件指针FILE。另外两个常用的类型是size_t和fpos_t,size_t是无符号整数的某种形式,是sizeof返回的结果的类型;fpos_t类型定义能够唯一说明文件中的每个位置的对象。
由头部定义的最有用的宏是EOF,其值代表文件的结尾。
1.clearerr
#include <stdio.h> void clearerr(FILE *stream);
把stream指向的文件错误标志复位(置0),文件尾标志也复位。
2.fclose
#include <stdio.h> int flcose(FILE *stream); 返回:成功为0,失败为非0
关闭与流stream联系的文件并对其缓冲区清仓,stream与文件脱钩,释放自动分配的缓冲区。
3.feof
#include <stdio.h> int feof(FILE *stream); 返回:到达文件尾时返回非0值,否则返回0
检查文件位置指示,由此确定与stream关联的文件中是否到达文件尾。
到达文件尾后,一切后续操作都返回EOF,直到调用rewind()后fseek()改变位置指示。
操作二进制文件时feof()特别有用,因为文件尾标志也是有效二进制值,所以必须使用feof()来确定是否到达文件尾。
4.ferror
#include <stdio.h> int ferror(FILE *stream); 返回:无错返回0,有错返回非0
在给定流stream上检查文件错误。可以用perror()确定错误的确切性质。
5.fflush
#include <stdio.h> int fflush(FILE *stream); 返回:成功为0,失败返回EOF
如果与stream关联的文件是“写打开”的,调用fflush()把输出缓冲区的内容物理的写入文件;如果文件是“读打开”的,则fflush()清除输入缓冲区的内容。文件维持打开不变。
程序正常结束或缓冲区满时,缓冲区自动清仓。
6.fgetc
#include <stdio.h> int fgetc(FILE *stream);
返回输入流stream中当前位置的下一个字符,并把文件位置指示值加1。
成功返回获得的字符。如果到达文件尾,返回EOF,因为EOF是有效的二进制值,所以处理二进制文件时还必须用feof()检查是否到达文件尾;如果发生错误,fgetc()也返回EOF,所以处理二进制文件时也必须用ferror()检查是否确实出错。
7.fgetpos
#include <stdio.h> int fgetpos(FILE *stream, fpost_t *position); 返回:成功返回0,失败返回非0
把指定流的文件位置指示器的当前值存入position指向的对象中。position指向的对象必须是fpos_t类型的。
8.fgets
#include <stdio.h> char *fgets(char *str, int num, FILE *stream); 返回:成功返回str,到达文件尾和失败都返回NULL
最多从流stream中读入num-1个字符,将读入内容放入str指向的字符数组中。读操作进行到遇到新行符(newline)或达到指定数目为止。如果输入新行符,则新行符被保留下来,并成为str串的一部分。
当发生读错误时,str指向的内容不确定。由于出错和到达文件尾都返回空指针,所以应该用feof()或ferror()确定实际情况。
9.fopen
#include <stdio.h> FILE *fopen(const char *fname, const char *mode); 返回:成功为文件指针,失败为NULL
打开以fname所指内容为名字的文件,返回与之关联的流。mode决定打开的方式,可选值如下:
“r” | 以文本方式“读打开”文件 |
“w” | 以文本方式“生成”并“写打开”文件 |
“a” | 向以文本方式打开的文件追加 |
“rb” | 以二进制方式“读打开” |
“wb” | 以二进制方式“生成”并“写打开”文件 |
“ab” | 向以二进制方式打开的文件追加 |
“r+” | 以文本方式“读/写打开“文件 |
“w+” | 以文本方式生成并“读/写打开“文件 |
“a+” | 以文本方式“读/写打开文件“,写只能追加 |
“rb+”或”r+b” | 以二进制方式“读/写打开“文件 |
“wb+”或”w+b” | 以二进制方式生成并“读/写打开“文件 |
“ab+”或”a+b” | 以二进制方式“读/写打开“文件,写追加 |
在以读/写方式打开的文件时,写操作和读操作之间必须调用fflush()、fseek()或rewind()。
10.fprintf
#include <stdio.h> int fprintf(FILE *stream, const char *format,…); 返回:成功为实际写出的字符数,出错返回负值
以format串说明的格式向stream指向的流中写变元表中变元的内容。
格式串中的转换字符以%开头,列表如下:
字 符 | 说明 |
---|---|
d, i | int;有符号十进制表示法 |
o | int;无符号八进制表示法(无前导0) |
x, X | int;无符号十六进制表示法(无前导0X和0x),对0x用abcdef,对0X用ABCDEF |
u | int;无符号十进制表示法 |
c | int;单个字符,转换为unsigned char类型后输出 |
s | char *;输出字符串直到'\0'或者达到精度指定的字符数 |
f | double;形如[-]mmm.ddd的十进制浮点数表示法,d的数目有精度确定。缺省精度为6位,精度为0时不输出小数点 |
e, E | double;形如[-]m.dddddde[+-]xx或者[-]m.ddddddE[+-]xx的十进制浮点数表示法,d的数目有精度确定。缺省精度为6位,精度为0时不输出小数点 |
g G | double;当指数值小于-4或大于等于精度时,采用%e或%E的格式;否则使用%f的格式。尾部的0与小数点不打印 |
p | void *;输出指针值(具体表示与实现相关) |
n | int *;到目前为止以此格式调用函数输出的字符的数目将被写入到相应变元中,不进行变元转换 |
% | 不进行变元转换,输出% |
在%与转换字符之间依次可以有下列标记:
标记 | 说明 |
---|---|
- | 指定被转换的变元在其字段内左对齐 |
+ | 指定在输出的数前面加上正负号 |
空格 | 如果第一个字符不是正负号,那么在其前面附加一个空格 |
0 | 对于数值转换,在输出长度小于字段宽度时,加前导0 |
# | 指定其他输出格式,对于o格式,第一个数字必须为零;对于x/X格式,指定在输出的非0值前加0x或0X;对于e/E/f/g/G格式,指定输出总有一个小数点;对于g/GG格式,还指定输出值后面无意义的0将被保留。 |
宽度[number] | 一个指定最小字段宽的数。转换后的变元输出宽度至少要达到这个数值。如果变元的字符数小于此数值,那么在变元左/右边添加填充字符。填充字符通常为空格(设置了0标记则为0)。 |
. | 点号用于把字段宽和精度分开 |
精度[number] | 对于字符串,说明输出字符的最大数目;对于e/E/f格式,说明输出的小数位数;对于g/G格式,说明输出的有效位数;对于整数,说明输出的最小位数(必要时可加前导0) |
h/l/L | 长度修饰符,h表示对应的变元按short或unsigned short类型输出;l表示对应的变元按long或unsigned long类型输出;L表示对应的变元按long double类型输出 |
在格式串中字段宽度和精度二者都可以用*来指定,此时该值可通过转换对应的变元来获得,这些变元必须是int类型。
11.fputc
#include <stdio.h> int fputc(int ch, FILE *stream); 返回:成功为写出的字符,出错为EOF
向指定的流stream的当前位置写字符ch,然后推进文件位置指示器,到达文件中的下一个位置。int参数的高字节被忽略。
对于二进制文件,EOF可能是有效的字符,所以判断出错时必须用ferror()决定。
12.fputs
#include <stdio.h> int fputs(const char *str, FILE *stream); 返回:成功返回非负值,失败返回EOF
向流stream写str串,不写串的null终止符。
13.fread
#include <stdio.h> size_t fread(void *buf, size_t size, size_t count, FILE *stream); 返回:实际读入的对象数
从流stream中读入count个对象,每个对象长size个字节,读入结果放到buf指向的数组中。文件位置指示按读入字节数向前推进相应字节位置。
返回值小于指定读入数,可能出错,也可能到达文件尾。应用feof()或ferror()确定实际情况。
14.freopen
#include <stdio.h> FILE *freopen(const char *fname, const char *mode, FILE *stream); 返回:成功为stream,失败为空指针
把现存的流联系到另一个文件。新文件名由fname指定,访问方式由mode指定,重分配的流由stream指定。freopen()先尝试关闭与stream关联的文件,不管成功与否,都继续打开新文件。
该函数的主要用途是把系统定义的标准流stdin、stdout、stderr重定向到其他文件。
15.fscanf
#include <stdio.h> int fscanf(FILE *stream, const char *format, …); 返回:成功为实际赋值的变元数,出错为EOF
类似于scanf(),但信息由stream指定的流读入。
函数返回实际赋值的变元数,其中不计算跳过的域数。返回EOF表示给第一个变元赋值前已经出错。
格式串format可以包含:
- 空格或制表符,他们将被忽略;
- 普通字符(%除外),与输入流中下一个非空白字符相匹配;
- 转换规格说明:由一个%、一个赋值屏蔽字符*(可选)、一个用于指定最大字段宽度的数(可选)、一个用于指定目标字段的字符h/l/L(可选)、一个转换字符组成。
转换字符列表如下:
字符 | 输入数据;变元类型 |
---|---|
d | 十进制整数;int * |
i | 整数;int *。该整数可以是以0开头的八进制数,也可以是以0x/0X开头的十六进制数 |
o | 八进制数(可以带或不带前导0);int * |
u | 无符号十六进制整数;unsigned int * |
x | 十六进制整数(可以带或不带前导0x/0X);int * |
c | 字符;char *。按照字段宽的大小把读入的字符保存在指定的数组中,不加入字符'\0'。字段宽的缺省值为1。在这种情况下,不跳过空白符;如果要读入下一个非空白符,使用%1s(数字1) |
s | 有非空白符组成的字符串(不包含银号);char *。该变元指针指向一个字符数组,该字符数组有足够空间来保存该字符串以及在末尾添加的'\0' |
e/f/g | 浮点数;float *。float浮点数的输入格式为:一个任选的正负号,一串可能包含小数点的数字和一个任选的指数字段。指数字段由字母e/E以及后跟的一个可能带正负号的整数组成 |
p | 指针值;void * |
n | 将到目前为止此调用所读的字符数写入变元;int *。不读入输入字符。不增加转换项目计数 |
[...] | 用方括号括起来的字符集中的字符来匹配输入,以找到最长的非空字符串;char *。在末尾添加'\0'。格式[]...]表示字符集中包含字符] |
[^...] | 用不在方括号里的字符集中的字符来匹配输入,以找到最长的非空字符串;char *。在末尾添加'\0'。格式[]...]表示字符集中包含字符] |
% | 字面值%,不进行赋值 |
如果变元是指向short类型而不是int类型的指针,那么在d/i/n/o/u/x这几个转换字符前可以加上字符h;
如果变元是指向long类型的指针,那么在d/i/n/o/u/x这几个转换字符前可以加上字符l;
如果变元是指向double类型而不是float类型的指针,那么在e/f/g这几个转换字符前可以加上字符l;
如果变元是指向long double类型的指针,那么在e/f/g前可以加上字符L。
16.fseek
#include <stdio.h> int fseek(FILE *stream, long int offset, int origin); 返回:成功为0,出错为非0
按照offset和origin的值设置与流stream相关联的文件位置指示器。
offset是从origin开始寻找的字节数。origin必须是如下的宏:
- SEEK_SET 从文件开始处寻址
- SEEK_CUR 从当前位置寻址
- SEEK_END 从文件结尾处寻址
fseek()清除与指定流关联的文件尾标志,还废除同一流上已执行的ungetc()的效果。
17.fsetpos
#include <stdio.h> int fsetpos(FILE *stream, const fpost_t *position);
把文件位置指示器移动到position所指对象确定的点。position对象的值必须是预先用fgetpos()取得的。
执行fsetpos()后,文件尾标志复位,先前调用ungetc()的结果都被废除。
18.ftell
#include <stdio.h> long int ftell(FILE *stream);
返回指定流的当前文件位置值。出错时返回-1。
19.fwrite
#include <stdio.h> size_t fwrite(const void *buf, size_t size, size_t count, FILE *stream); 返回:实际写入的对象数
把buf指向的字符数组中的count个对象写到流stream中,每个对象长度为size个字节。文件位置指示器向前推进,推进值等于实际写入的字符数。
函数成功,返回值等于count。如写入对象数小于count,表示出错。
20.getc
#include <stdio.h> int getc(FILE *stream);
getc()与fgetc()完全一样。多数实现中都将getc()定义为宏。
21.getchar
#include <stdio.h> int getchar(void); 返回:所读字符,出错或文件尾为EOF
从stdin中返回下一个字符。字符先按unsigned char型读入,转为int型后返回。
getchar()常定义为宏。
22.gets
#include <stdio.h> char *gets(char *str); 返回:成功为str,失败为NULL
从stdin中读字符串,读入结果放到str指向的字符数组中,一直到接收到新行符或EOF为止。新行符不作为读入串的内容,读入的新行符变成null值,由此结束字符串。
当发生读错误时,str数组的内容不确定。到达文件尾和出错都返回NULL,所以必须用feof()或ferror()来确定实际情况。
gets()可读入无限多字节,所以要保证str有足够的空间,防止溢出。
23.perror
#include <stdio.h> void perror(const char *str);
把全局变量errno的值映射到一个串,然后在流stderr上写出该串。如str不为空则先写str串,然后写一个冒号,最后再写与实现相关的错误信息。
24.printf
#include <stdio.h> int printf(const char *format, …);
在format所指格式串的控制下,向stdout写变元表中的变元值。函数返回实际写入的字节数,出错返回负值。
25.putc
#include <stdio.h> int putc(int ch, FILE *stream);
等效于fputc()。putc()常作为宏来实现。
26.putchar
#include <stdio.h> int putchar(int ch);
putchar()等价于putc(ch, stdou)。
27.puts
#include <stdio.h> int puts(const char *str); 返回:成功返回非负值,失败返回EOF
把串str写到标准输出设备上,其中的null终结符转换为新行(newline)。
28.remove
#include <stdio.h> int remove(const char *fname); 返回:成功为0,失败为非0值
删除以fname串为名字的文件。
29.rename
#include <stdio.h> int rename(const char *oldfname, const char *newfname); 返回:成功为0,失败为非0值
把文件的名字从oldfname该为newfname。newfnamebu不允许与现存的目录项匹配。
30.rewind
#include <stdio.h> void rewind(FILE *stream);
把文件位置移到指定流的开始处,同时清除与该流相关的文件尾标志和错误标志。
31.scanf
#include <stdio.h> int scanf(const char *format, …); 返回成功赋值的域数的值,出错返回EOF
从标准输入流stdin中读内容。
32.setbuf
#include <stdio.h> void setbuf(FILE *stream, char *buf);
buf为空指针时,setbuf()停止对流stream的缓冲处理;buf为非空指针时,setbuf()把流的缓冲区置为buf所指区域。
说明自己定义的缓冲区时,缓冲区尺寸必须为BUFSIZ个字节。
33.setvbuf
#include <stdio.h> int setvbuf(FILE *stream, char *buf, int mode, size_t size); 成功返回0,失败返回非0
给指定的流定义缓冲区、缓冲区的大小和缓冲的方式。buf指向的字符数组为流的I/O缓冲区,size表示缓冲区的大小,mode指定缓冲的处理方式。如果buf为空指针,setvbuf()将自行分配缓冲空间。
mode的有效值是:
- _IOFBF 全缓冲
- _IOLNF 不缓冲
- _IOLBF 行缓冲
34.snprintf
#include <stdio.h> int snprintf(char *buf, size_t num, const char *format, …);
除了最多为num-1个字符被存放到buf指向的数组之外,snprintf和sprintf完全相同。数组以null结束。
35.sprintf
#include <stdio.h> int sprintf(char *buf, const char *format, …); 返回:实际写到字符数组的字符数
与printf()基本相同,但输出写到字符数组buf而不是stdout中。由buf指向的数组以空(null)结尾。
注意,sprintf()不对buf进行边界检查。
36.sscanf
#include <stdio.h> int sscanf(const char *buf, const char *format, …); 返回:实际赋值的变量数,出错为EOF
与scanf()基本相同,但sscanf()从buf指向的数组中读,而不是stdin。
37.tmpfile
#include <stdio.h> FILE *tmpfile(void); 返回:成功为流指针,失败为空指针
为读写操作打开一个临时的二进制文件,并返回该流的指针,函数自动构造唯一的文件名,以便不与现存文件冲突。
产生的临时文件在关闭文件或程序终止时都自动删除。
38.tmpnam
#include <stdio.h> char *tmpnam(char *name); 返回:成功为非空指针,失败为NULL
生成一个唯一的文件名,结果放在字符数组name中。该函数的主要用途是生成与目录中其他文件不重名的临时文件名。
函数最多可以调用TMP_MAX次。
如果name为NULL,则返回指向含有该文件名的固定分配的内存区的指针。
39.ungetc
#include <stdio.h> int ungetc(int ch, FILE *stream); 返回:成功时为ch,失败为EOF
把ch中的低字节返回到输入流stream中,下次对该流读操作时,先读该字节。
当调用fflush()、fseek()或rewind()时废除ungetc()操作,并放弃输入的字符。
对ungetc()的调用将清除与指定流关联的文件尾标志。
40.vprintf、vfprintf、vsprintf、vsnprintf
#include <stdarg.h> #include <stdio.h> int vprintf(char *format, va_list arg_ptr); int vfprintf(FILE *stream, const char *format, va_list arg_ptr); int vsprintf(char *buf, const char *format, va_list arg_ptr); int vsnprintf(char *buf, size_t num, const char *format, va_list arg_ptr);
使用举例:
void print_message( char *format, … ) { va_list ptr; va_start(ptr, format); vprintf(format, ptr); va_end(ptr); }
41.vscanf、vfscanf、vsscanf
#include <stdarg.h> #include <stdio.h> int vscanf(char *format, va_list arg_ptr); int vfscanf(FILE *stream, const char *format, va_list arg_ptr); int vsscanf(char *buf, const char *format, va_list arg_ptr);