每个编程语言学到文件操作、字符串操作、网络连接什么什么的就开始有各种各样的库函数需要记忆,有的比较常用还比较好记,有的遇到了却没记住,那就只能请教Google了。但考试时候不能Google,本篇旨在总结C语言中常见的文件处理操作,便于查阅和记忆。
- FILE文件类型
- fopen() 打开文件
- fclose() 关闭文件
- fputc() 将字符写入文件
- fputs() 将字符串写入文件
- fprintf() 格式化写入
- fgetc() 从文件中读取字符
- fgets() 从文件中读取字符串
- fscanf() 格式化读取
- fwrite() 二进制写入
- fread() 二进制读取
- rewind() 位置指针指向文件头
- fseek() 改变文件位置指针
- ftell() 获取文件位置指针相对于文件头的位置
- fflush() 刷新流 stream 的输出缓冲区
- feof() 测试给定流 stream 的文件结束标识符
- freopen()
- remove() 删除文件
- rename() 重命名/移动文件
FILE文件类型
FILE类型是一个用来表示文件的结构体
其在TC2.0编译器中的原型如下:
1 | typedef struct { |
其在VC6.0编译器中的原型如下:
1 | struct _iobuf { |
在日常使用中,FILE类型常以指针形式使用。
fopen() 打开文件
该函数用于打开一个文件,函数原型如下:
1 | FILE *fopen( const char * filename, const char * mode ); |
该函数接收两个字符串类型参数,函数将会打开一个文件,并将建立这个文件的FILE类型变量,并且返回一个指向该变量的FILE类型指针。
其中,
filename
表示文件地址,数据类型为字符串,允许使用相对地址或绝对地址。例如在Windows系统下"D:\\data\\file.txt"
可以用来表示地址,在Linux系统下"/mnt/test.txt"
可以用来表示地址;
mode
表示访问模式,数据类型为字符串,它的值可以为下列几种:
模式 | 描述 |
---|---|
r | 打开一个已有的文本文件,允许读取文件。 |
w | 打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容。如果文件存在,则该会被截断为零长度,重新写入。 |
a | 打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。 |
r+ | 打开一个文本文件,允许读写文件。 |
w+ | 打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件。 |
a+ | 打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。 |
rb | 打开一个已有的二进制文件,允许读取文件。 |
wb | 打开一个二进制文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容。如果文件存在,则该会被截断为零长度,重新写入。 |
ab | 打开一个二进制文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。 |
rb+ | 打开一个二进制文件,允许读写文件。 |
wb+ | 打开一个二进制文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件。 |
ab+ | 打开一个二进制文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。 |
Example:
1 | FILE *fp = fopen("/tmp/test.txt", "w+"); |
fclose() 关闭文件
该函数用于关闭一个文件,函数原型如下:
1 | int fclose( FILE *fp ); |
该函数接收一个FILE类型指针变量,将会关闭这个FILE类型指针变量指向的文件,并且返回一个int类型的值。
其中
fp
为一个指向所要关闭文件的FILE类型指针;
如果成功关闭文件,fclose( )
函数返回零,如果关闭文件时发生错误,函数返回 EOF
。这个函数实际上,会清空缓冲区中的数据,关闭文件,并释放用于该文件的所有内存。EOF
是一个定义在头文件 stdio.h
中的常量。
Example:
1 | fclose(fp); |
fputc() 将字符写入文件
该函数用于将字符输出/写入到文件中,其原型如下:
1 | int fputc( int c, FILE *fp ); |
该函数接收一个int类型参数c
和一个FILE类型指针fp
,会将ASCII码为c
的单个字符写入到fp
指针所指向的文件中。如果写入成功,位置指针会自动后移一个字节的位置,并且返回c
作为函数的返回值。如果写入失败,则返回EOF
。
其中,
c
为要写入字符的ASCII码;
fp
为指向要写入文件的FILE类型指针。
Example:
1 | fputc(48,fp); |
fputs() 将字符串写入文件
该函数用于将字符串输出/写入到文件中,其原型如下:
1 | int fputs( const char *s, FILE *fp ); |
该函数接收一个char类型指针变量s
和一个FILE类型指针变量fp,可以将指针s指向的字符串写入到fp所指向的文件中,如果写入成功,位置指针自动后移相应字节数,并且返回一个非负整数;否则,返回EOF
。
注意:指针s指向的字符串需以\0
结束,但写入字符串时不会写入\0
。
其中,
s
为char类型指针变量,指向要写入的字符串的首地址;
fp
为FILE类型指针变量,指向要写入的文件。
Example:
1 | fputs("hello",fp); |
fprintf() 格式化写入
该函数用于格式化写入文件,其原型如下:
1 | int fprintf(FILE *stream, const char *format, ...); |
基本用法与printf()
函数类似,接收若干个参数,第一个参数为文件指针,剩余参数与printf()
函数类似,如果写入成功,则返回写入的字符总数,否则返回一个负数。
其中,
stream
为指向输出文件的FILE类型指针。当该参数为stdout
时该函数功能与printf()
函数相同。
format
是 C 字符串,包含了要被写入到流 stream 中的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。format 标签属性是 %[flags][width][.precision][length]specifier
,具体讲解如下:
specifier(说明符) | 输出 |
---|---|
c | 字符 |
d 或 i | 有符号十进制整数 |
e | 使用 e 字符的科学科学记数法(尾数和指数) |
E | 使用 E 字符的科学科学记数法(尾数和指数) |
f | 十进制浮点数 |
g | 自动选择 %e 或 %f 中合适的表示法 |
G | 自动选择 %E 或 %f 中合适的表示法 |
o | 有符号八进制 |
s | 字符的字符串 |
u | 无符号十进制整数 |
x | 无符号十六进制整数 |
X | 无符号十六进制整数(大写字母) |
p | 指针地址 |
n | 无输出 |
% | 字符 |
flags(标识) | 描述 |
---|---|
- | 在给定的字段宽度内左对齐,默认是右对齐(参见 width 子说明符)。 |
+ | 强制在结果之前显示加号或减号(+ 或 -),即正数前面会显示 + 号。默认情况下,只有负数前面会显示一个 - 号。 |
(space) | 如果没有写入任何符号,则在该值前面插入一个空格。 |
# | 与 o、x 或 X 说明符一起使用时,非零值前面会分别显示 0、0x 或 0X。 与 e、E 和 f 一起使用时,会强制输出包含一个小数点,即使后边没有数字时也会显示小数点。默认情况下,如果后边没有数字时候,不会显示显示小数点。 与 g 或 G 一起使用时,结果与使用 e 或 E 时相同,但是尾部的零不会被移除。 |
0 | 在指定填充 padding 的数字左边放置零(0),而不是空格(参见 width 子说明符)。 |
width(宽度) | 描述 |
---|---|
(number) | 要输出的字符的最小数目。如果输出的值短于该数,结果会用空格填充。如果输出的值长于该数,结果不会被截断。 |
* | 宽度在 format 字符串中未指定,但是会作为附加整数值参数放置于要被格式化的参数之前。 |
.precision(精度) | 描述 |
---|---|
.number | 对于整数说明符(d、i、o、u、x、X):precision 指定了要写入的数字的最小位数。如果写入的值短于该数,结果会用前导零来填充。如果写入的值长于该数,结果不会被截断。精度为 0 意味着不写入任何字符。 对于 e、E 和 f 说明符:要在小数点后输出的小数位数。 对于 g 和 G 说明符:要输出的最大有效位数。 对于 s: 要输出的最大字符数。默认情况下,所有字符都会被输出,直到遇到末尾的空字符。 对于 c 类型:没有任何影响。 当未指定任何精度时,默认为 1。如果指定时不带有一个显式值,则假定为 0。 |
.* | 精度在 format 字符串中未指定,但是会作为附加整数值参数放置于要被格式化的参数之前。 |
length(长度) | 描述 |
---|---|
h | 参数被解释为短整型或无符号短整型(仅适用于整数说明符:i、d、o、u、x 和 X)。 |
l | 参数被解释为长整型或无符号长整型,适用于整数说明符(i、d、o、u、x 和 X)及说明符 c(表示一个宽字符)和 s(表示宽字符字符串)。 |
L | 参数被解释为长双精度型(仅适用于浮点数说明符:e、E、f、g 和 G)。 |
fgetc() 从文件中读取字符
该函数用于从文件中读取一个字符,其原型如下:
1 | int fgetc( FILE * fp ); |
该函数接收一个指向所要读取的文件的FILE类型指针,函数从fp
所指向的输入文件中读取一个字符。如果读取成功,返回值是所读取的字符的ASCII码值,并且位置指针向后移动一个字节;如果发生错误则返回 EOF。
Example:
1 | char ch=fgetc(fp); |
fgets() 从文件中读取字符串
该函数用于从文件中读取一个字符串,其原型如下:
1 | char *fgets( char *buf, int n, FILE *fp ); |
该函数接收一个char类型指针buf
,一个int类型变量n
,一个FILE类型指针fp
。
函数从fp
所指向的文件中读取 n - 1 个字符。它会把读取的字符串复制到buf
所指向的字符串,并在最后追加一个NULL
字符来终止字符串。如果这个函数在读取最后一个字符之前就遇到一个换行符 ‘\n’ 或文件的末尾 EOF,则只会返回读取到的字符,包括换行符。读取成功后位置指针自动向后移动 n - 1 个字节位置。
函数返回值为char类型指针buf
。
其中,
buf
为cahr类型指针变量,指向将要储存字符串的首地址;
n
为int类型变量,表示要读取字符串长度(包括\0
);
fp
为FILE类型指针变量,指向要读取的文件。
fscanf() 格式化读取
该函数用于格式化读取文件,其原型如下:
1 | int fscanf(FILE *stream, const char *format, ...); |
基本用法与scanf()
函数类似,接收若干个参数,第一个参数为文件指针,剩余参数与scacnf()
函数类似,如果读取成功,该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误,则返回 EOF。
其中,
stream
为指向输出文件的FILE类型指针。当该参数为stdin
时该函数功能与printf()
函数相同。
format
是 C 字符串,包含了以下各项中的一个或多个:空格字符、非空格字符 和 format 说明符。
format 说明符形式为 [=%[*][width][modifiers]type=]
,具体讲解如下:
参数 | 描述 |
---|---|
* | 这是一个可选的星号,表示数据是从流 stream 中读取的,但是可以被忽视,即它不存储在对应的参数中。 |
width | 这指定了在当前读取操作中读取的最大字符数。 |
modifiers | 为对应的附加参数所指向的数据指定一个不同于整型(针对 d、i 和 n)、无符号整型(针对 o、u 和 x)或浮点型(针对 e、f 和 g)的大小: h :短整型(针对 d、i 和 n),或无符号短整型(针对 o、u 和 x) l :长整型(针对 d、i 和 n),或无符号长整型(针对 o、u 和 x),或双精度型(针对 e、f 和 g) L :长双精度型(针对 e、f 和 g) |
type | 一个字符,指定了要被读取的数据类型以及数据读取方式。具体参见下一个表格。 |
类型说明符 | 合格的输入 | 参数的类型 |
---|---|---|
c | 单个字符:读取下一个字符。如果指定了一个不为 1 的宽度 width,函数会读取 width 个字符,并通过参数传递,把它们存储在数组中连续位置。在末尾不会追加空字符。 | char * |
d | 十进制整数:数字前面的 + 或 - 号是可选的。 | int * |
e,E,f,g,G | 浮点数:包含了一个小数点、一个可选的前置符号 + 或 -、一个可选的后置字符 e 或 E,以及一个十进制数字。两个有效的实例 -732.103 和 7.12e4 | float * |
o | 八进制整数。 | int * |
s | 字符串。这将读取连续字符,直到遇到一个空格字符(空格字符可以是空白、换行和制表符)。 | char * |
u | 无符号的十进制整数。 | unsigned int * |
x,X | 十六进制整数。 | int * |
fwrite() 二进制写入
该函数用于将指定位置开始的指定字节数的内容写入到文件中,函数原型如下:
1 | size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp); |
(size_t 是在 stdio.h 和 stdlib.h 头文件中使用 typedef 定义的数据类型,表示无符号整数,也即非负数,常用来表示数量。)
该函数接受4个参数,用于从内存的ptr
地址开始,将连续n*size
个字节的内容原样复制到fp
所指向的文件中。并返回实际写入的数据块个数。
其中,
ptr
为无类型指针变量,表示要输出数据在内存中的首地址;
size
为一个数据块的字节数;
n
为数据块的个数;
fp
为FILE类型的指针,指向要写入的文件。
Example:
1 |
|
fread() 二进制读取
该函数用于读取文件中从当前位置开始的指定字节数内容,然后直接存储到内存中指定起始地址的内存空间中。其函数原型如下:
1 | size_t fread(void *ptr, size_t size, size_t n, FILE *fp) |
该函数接受四个参数,从fp
打开的文件的当前位置开始,连续读取n*size
个字节的内容,存储到ptr
为首地址的内存中,返回值为实际读取到内存中的数据块个数。
其中,
ptr
为无类型指针,表示要输入数据在内存中的首地址;
size
表示一个数据块的字节数;
n
为数据块的个数;
fp
为FILE类型的指针,指向要读取的文件。
Example:
1 |
|
rewind() 位置指针指向文件头
该函数可以使位置指针指向文件头,函数原型如下:
1 | void rewind(FILE *fp); |
使fp
指针指向的文件的位置指针指向文件头,同时清除和文件流相关的错误和EOF标记,无返回值。
fseek() 改变文件位置指针
该函数可以改变位置指针,其原型如下:
1 | int fseek(FILE *fp, long int offset, int from); |
该函数可以将文件位置从from
开始移动offset
个字节。执行成功返回0
,不成功返回非零值。
其中,
fp
为文件指针;
offset
为移动的字节数,当其为正数时表示向末尾移动,负数表示向前移动,且必须为长整形数;
from
为起始位置,他的取值如下:
常量 | 等效数字 | 描述 |
---|---|---|
SEEK_SET | 0 | 文件的开头 |
SEEK_CUR | 1 | 文件指针的当前位置 |
SEEK_END | 2 | 文件的末尾 |
Example:
1 |
|
ftell() 获取文件位置指针相对于文件头的位置
该函数用于获取文件位置指针相对于文件头的位置,原型如下:
1 | long int ftell(FILE *fp); |
fp
为文件指针,返回位置指针相对于文件头的偏移字节数,如果出错则返回-1L
。
fflush() 刷新流 stream 的输出缓冲区
通俗讲就是更新对文件的修改,其函数原型如下:
1 | int fflush(FILE *fp); |
fp
为文件指针。如果成功,该函数返回零值。如果发生错误,则返回 EOF,且设置错误标识符(即 feof)。
feof() 测试给定流 stream 的文件结束标识符
该函数用于检测文件的位置指针是否到达文件末尾,其原型如下:
1 | int feof(FILE *stream); |
fp
为文件指针。到达文件末尾时返回非零值,否则返回0。
freopen()
该函数用于把一个新的文件名 filename 与给定的打开的流 stream 关联,同时关闭流中的旧文件。通常用于将输入输出重定向到文件。其原型如下:
1 | FILE *freopen(const char *filename, const char *mode, FILE *stream); |
filename
字符串包含了要打开文件的名称;
stream
是指向 FILE 对象的指针,该 FILE 对象标识了要被重新打开的流。当其为stdout
时为将输出重定向到文件,当其为stdin
时为重定向输入到文件。
mode
为字符串,表示文件访问模式,与fopen
用法一样。
返回值:如果文件成功打开,则函数返回一个指针,指向用于标识流的对象。否则,返回空指针。
Example:
1 | fp = freopen("file.txt", "w+", stdout); |
remove() 删除文件
该函数用于删除给定的文件名 filename
,以便它不再被访问。其原型如下:
1 | int remove(const char *filename); |
filename
表示文件地址,数据类型为字符串,允许使用相对地址或绝对地址。例如在Windows系统下"D:\\data\\file.txt"
可以用来表示地址,在Linux系统下"/mnt/test.txt"
可以用来表示地址.
如果成功,则返回零。如果错误,则返回 -1,并设置 errno。
rename() 重命名/移动文件
该函数用于把 old_filename
所指向的文件名改为 new_filename
。可以实现文件重命名/移动。其原型如下:
1 | int rename(const char *old_filename, const char *new_filename); |
其中,
old_filename
为要重命名的文件名;
new_filename
为新的文件名。
如果成功,则返回零。如果错误,则返回 -1,并设置 errno。