输入/输出函数
打开流
FILE *fopen(char const *name, char const *mode)'
name
是打开的文件或设备的名字,mode
参数提示流是用于只读、只写还是读写,是文本流还是二进制流。
读取 | 写入 | 添加 | |
---|---|---|---|
文本 | "r" | "w" | "a" |
二进制 | "rb" | "wb" | "ab" |
始终需要检查
fopen
函数的返回值
freopen
函数用于打开(重新打开)一个特定的文件流
FILE *freopen(char const *name, char const *mode, FILE *stream);
这个函数首先尝试关闭流,然后用指定的文件和模式重新打开这个流。打开失败返回 NULL ,打开成功就返回第三个参数的值。
关闭流
int fclose(FILE *f);
fclose
函数在文件关闭之前刷新缓存区,执行成功返回值为0,执行失败则返回EOF
.
//处理每个出现于命令行的文件
#include <stdio.h>
#include <stdlib.h>
int main(int ac, char **av)
{
int exit_status = EXIT_SUCCESS;
FILE *input;
//当还有更多文件名时
while(*++av != NULL)
{
//尝试打开文件
input = fopen(*av, "r");
if(input == NULL)
perror(*av);
exit_status = EXIT_FAILURE;
continue;
}
//处理文件
//关闭文件
if(fclose(input) != 0)
{
perror("fclose");
exit(EXIT_FAILURE);
}
return exit_status;
}
字符IO
getchar 函数家族
int fgetc(FILE *stream);
int getc(FILE *stream);
int getchar(void);
getchar 始终从标准输入读取,返回类型都是int,因为EOF
为int型。
putchar 函数家族
int fputc(int character, FILE *stream);
int putc(int character,FILE *stream);
int putchar(int character);
在打印之前,函数把这个整型参数裁剪为一个无符号字符型值。
撤销字符IO
int ungetc(int character,FILE *stream);
可以将字符退回流
未格式的行IO
char *fgets(char *buffer, int buffer_size, FILE *stream);
char *gets(char *buffer); //无size参数 只能是玩具程序
int fputs(char const *buffer, FILE *stream);
int puts(char const *buffer);
fgets 从指定的stream中读取字符并把它们复制到buffer中,当读取到一个换行符并存储到缓冲区之后就不再读取,或者缓冲区的字符数达到 buffer_size -1 时它也停止读取。任何情况下,一个 NUL 字节将被添加到缓冲区所存储数据的末尾,使它成为一个字符串。
格式化的行IO
scanf
函数家族:
int fscanf(FILE *stream, char const *format, ...); //参数源
int scanf(char const *format, ...); //标准输入源
int sscanf(char const *string, char const *format, ...); //第一个参数字符串
这些函数都从输入源读取字符并根据format
字符串给出的格式代码对它们进行转换,被转换的输入值的数目作为函数的返回值返回。
代码 | 参数 | 含义 |
---|---|---|
c | char * | 读取存储单个字符,前导空白字符不跳过,可按给出宽度读取,字符后不会加NUL ,必须指向足够大的数组 |
i d | int * | 一个可选的有符号整数被转换,d 解释为十进制数,i 根据第一个字符决定值的基数 |
u o x | unsigned * | 一个可选的有符号整数被转换,但按照无符号存储,u 解释为十进制,o 解释为八进制数,x 解释为十六进制数 |
e f g | float * | 期待一个浮点值,小数点非必须 |
s | char * | 读取一串非空白字符,发现空白输入就停止,参数必须指向足够大的字符串,字符串自动加上NUL |
[xxx] | char * | 根据组合的字符从输入中读取一串字符,参数必须指向足够大的字符串,遇到第一个不在给定组合中出现的字符时,输入就停止,会自动加NUL |
p | void * | 预期为一串字符串 |
n | int * | 到目前为止通过这个scanf函数的调用从输入读取的字符数被返回 |
printf
函数家族:
int fprintf(FILE *stream, char const *format, ...);
int printf(char const *format, ...);
int sprintf(char *buffer, char const *format, ...);
fprintf
输出到指定输出流,printf
输出到标准输出,sprintf
把它的结果作为一个NUL
结尾的字符串存储到指定的buffer
缓冲区。三个函数的返回是实际打印或者存储的字符数。
注意:sprintf
无缓冲区大小参数,要注意写入的长度
代码 | 参数 | 含义 |
---|---|---|
c | int | 参数被裁剪为 unsigned char 类型并作为字符打印 |
d i | int | 作为十进制打印 |
u o x,X | unsigned int | 作为一个无符号值打印,u 十进制,o 八进制,x 十六进制,X 十六进制大写 |
e E | double | 制数形式打印 |
f | double | 浮点 |
g G | doubel | 根据精度字段 |
s | char * | 打印一个字符串 |
p | void * | 因编译器而异的可打印字符 |
n | int * | 不产生输出,相反,到目前为止函数输出的字符数将被保存到对应的参数中 |
printf
示例
# 表示空格
A | ABC | ABCDEFGH | |
---|---|---|---|
%s | A | ABC | ABCDEFGH |
%5s | ####A | ##ABC | ABCDEFGH |
%.5s | A | ABC | ABCDEF |
%5.5s | ####A | ##ABC | ABCDE |
%-5s | A#### | ABC## | ABCDEFGH |
1 | -12 | 12345 | 123456789 | |
---|---|---|---|---|
%d | 1 | -12 | 12345 | 1234567 |
%6d | #####1 | ###-12 | #12345 | 123456789 |
%.4d | 0001 | -0012 | 12345 | 123456789 |
%6.4d | ##0001 | #-0012 | #12345 | 123456789 |
%-4d | 1### | -12# | 12345 | 123456789 |
%+d | +1 | -12 | +12345 | +123456789 |
1 | .01 | .00012345 | 12345.6789 | |
---|---|---|---|---|
%f | 1.000000 | 0.010000 | 0.000123 | 12345.678900 |
%10.2f | ######1.00 | ######0.01 | ######0.00 | ##12345.68 |
%e | 1.000000e+00 | 1.000000e-02 | 1.234500e-04 | 1.234568e+04 |
%.4e | 1.0000e+00 | 1.0000e-02 | 1.2345e-04 | 1.2346e+04 |
%g | 1 | 0.01 | 0.00012345 | 12345.7 |
二进制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 是输入输出流。它们的返回值是实际写入或者读取的元素的数目,如果出现了错误,此数目比请求的元素数目要小。
刷新和定位函数
int fflush(FILE *stream);
需要立即把输出缓冲区的数据进行物理写入时,使用 fflush 进行强制刷新
long ftell(FILE *stream);
int fseek(FILE *stream, long offset, int from);
ftell 返回流的当前位置,即下一个读取或者写入的将要开始的位置距离文件起始位置的偏移量。
fseek 函数允许在一个流中定位,第一个参数是需要改变的流,
|如果from 是|将定位到|
|-|—|
|SEEK_SET|从流起始位置 offset 个字节, offset 必须非负|
|SEEK_CUR|从流当前位置 offset 个字节,offset 可正可负|
|SEEK_END|从流尾部位置 offset 个字节,offset 可正可负(二进制流可能不支持|
改变缓冲方式
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
需要用到时仔细研究。
流错误函数
int feof(FILE *stream);
int ferror(FILE *stream);
void clearerr(FILE *stream);
文件操纵函数
int remove(char const *filename);
int rename(char const *olename, char const *newname);