函数原型:FILE * fopen(const char * path, const char * mode);
参数说明:
参数 path字符串包含欲打开的文件路径及文件名,参数mode 字符串则代表着流形态。
返回值:文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回 NULL,并把错误代码存在error中。
例:
//r 以只读方式打开文件,该文件必须存在,并且打开文件后只允许读数据。
#include<stdlib.h>
#include<stdio.h>
int main()
{
FILE*fp;
fp=fopen("D:\\file01.txt","r");
if(fp==NULL)
{
printf("Can not openthe file!\n");
exit(0);
}
fclose(fp);
return 0;
}
Function(函数) | Required header(头文件) |
fopen | <stdio.h> |
mode 有下表所示18种常见形态的字符串:
序号 | 使用方式 | 处理方式 | 打开文件不存在时 | 打开文件存在时 |
1 | r | 只读(文本文件) | 出错 | 正常打开 |
2 | w | 只写(文本文件) | 创建新文件 | 文件原内容丢失 |
3 | a | 追加(文本文件) | 创建新文件 | 在文件原有内容后面追加 |
4 | r+ | 读/写(文本文件) | 出错 | 正常打开 |
5 | w+ | 写/读(文本文件) | 建立新文件 | 文件原有内容丢失 |
6 | a+ | 读/追加(文本文件) | 建立新文件 | 在文件原有内容后面追加 |
7 | rt (同1) | 只读(文本文件) | 出错 | 正常打开 |
8 | wt (同2) | 只写(文本文件) | 创建新文件 | 文件原内容丢失 |
9 | at (同3) | 追加(文本文件) | 创建新文件 | 在文件原有内容后面追加 |
10 | rb | 只读(二进制文件) | 出错 | 正常打开 |
11 | wb | 只写(二进制文件) | 建立新文件 | 文件原有内容丢失 |
12 | ab | 追加(二进制文件) | 建立新文件 | 在文件原有内容后面追加 |
13 | rt+ (同4) | 读/写(文本文件) | 出错 | 正常打开 |
14 | wt+ (同5) | 写/读(文本文件) | 建立新文件 | 文件原有内容丢失 |
15 | at+ (同6) | 读/追加(文本文件) | 建立新文件 | 在文件原有内容后面追加 |
16 | rb+ | 读/写(二进制文件) | 出错 | 正常打开 |
17 | wb+ | 写/读(二进制文件) | 建立新文件 | 文件原有内容丢失 |
18 | ab+ | 读/追加(二进制文件) | 建立新文件 | 在文件原有内容后面追加 |
下面详细论述一下:
1."r"
Opens for reading.If the file does not exist or cannot be found, the fopen call fails.
打开文件用于读。若文件不存在也就是说无法被找到时,会导致fopen失败。
以只读的方式打开文件,该文件必须存在。此操作只能读取数据。
2."w"
Opens an empty file for writing. If the given file exists, its contents are destroyed.
打开一个空文件用于写,若该文件已存在,则里面的数据将会被清除。
以只写的方式打开一个空文件,若文件存在则长度清为 0,即该文件内容消失,若不存在则创建该文件。此操作只能写入数据。
3."a"
Opens for writing at the end of the file (appending) without removing the end-of-file (EOF)marker before new data is written to the file. Creates the file if it does not exist.
打开文件用于在文件尾添写新数据,在给文件写入新数据时EOF符将不会被删除。若文件不存在则创建该文件。
以附加的方式打开只写文件,用于在文件尾添写新数据。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留,在写入新数据时原来的EOF 符将不会被删除。此操作只能在文件尾添写新数据。
4."r+"
Opens for both reading and writing. The file must exist.
打开文件用于读和写。该文件必须存在。
以读/写的方式打开文件,该文件必须存在。此操作可以读取或写入数据。
5."w+"
Opens an empty file for both reading and writing. If the file exists, its contents are destroyed.
打卡一个空文件用于读/写,若该文件已存在,则里面的数据将会被清除。
以读/写的方式打开一个空文件,若文件存在则长度清为 0,即该文件内容消失,若不存在则创建该文件。此操作可以读取或写入数据。
6."a+"
Opens for reading and appending. The appending operation includes the removal of the EOF marker before new data is written to the file. The EOF marker is not restored after writing is completed. Creates the file if it does not exist.
打开文件用于读取数据和在文件尾添写数据,该操作将会在给文件写入新数据时把EOF符删除。在写完数据后,EOF符将不会被重新存进去。若文件不存在则创建该文件。
以附加的方式打开可读/写的文件,用于读取数据和在文件尾添写新数据。若文件不存在,则会建立该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留,在写入新数据时原来的 EOF 符将会被删除。此操作可以读取数据和在文件尾添写新数据。
7."rt"
以只读的方式打开一个文本文件(默认方式,和"r"相同),该文件必须存在。此操作只能读取数据。
8."wt"
以只写的方式打开一个空的文本文件(默认方式,和"w"相同),若文件存在则长度清为 0,即该文件内容消失,若不存在则创建该文件。此操作只能写入数据。
9."at"
以附加的方式打开一个只写的文本文件,用于在文件尾添写新数据(默认方式,和"a"相同)。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留,在写入新数据时原来的EOF 符将不会被删除。此操作只能在文件尾添写新数据。
10."rb"
以只读的方式打开一个二进制文件(非默认方式,若不加"b",则默认打开的是一个文本文件),该文件必须存在。此操作只能读取数据。
11."wb"
以只写的方式打开一个空的二进制文件(非默认方式,若不加"b",则默认打开的是一个文本文件),若文件存在则长度清为 0,即该文件内容消失,若不存在则创建该文件。此操作只能写入数据。
12."ab"
以附加的方式打开一个只写的二进制文件,用于在文件尾添写新数据(非默认方式,若不加"b",则默认打开的是一个文本文件)。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留,在写入新数据时原来的EOF 符将不会被删除。此操作只能在文件尾添写新数据。
13."rt+"
以读/写的方式打开一个文本文件(默认方式,和"r+"相同),该文件必须存在。此操作可以读取或写入数据。
14."wt+"
以读/写的方式打开一个空的文本文件(默认方式,和"w+"相同),若文件存在则长度清为 0,即该文件内容消失,若不存在则创建该文件。此操作可以读取或写入数据。
15."at+"
以附加的方式打开可读/写的一个文本文件,用于读取数据和在文件尾添写新数据(默认方式,和"a+"相同)。若文件不存在,则会建立该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留,在写入新数据时原来的 EOF 符将会被删除。此操作可以读取数据和在文件尾添写新数据。
16."rb+"
以读/写的方式打开一个二进制文件(非默认方式,若不加"b",则默认打开的是一个文本文件),该文件必须存在。此操作可以读取或写入数据。
17."wb+"
以读/写的方式打开一个空的二进制文件(非默认方式,若不加"b",则默认打开的是一个文本文件),若文件存在则长度清为 0,即该文件内容消失,若不存在则创建该文件。此操作可以读取或写入数据。
18."ab+"
以附加的方式打开一个可读/写的二进制文件,用于读取数据和在文件尾添写新数据(非默认方式,若不加"b",则默认打开的是一个文本文件)。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留,在写入新数据时原来的 EOF 符将会被删除。此操作可以读取数据和在文件尾添写新数据。
注意:
1.在使用"a"和"a+"访问类型的操作时为何不能覆盖已有数据?
When a file is opened by using the "a"
access type or the "a+"
access type, all write operations occur at the end of the file. The file pointer can be repositioned by using fseek
or rewind
, but is always moved back to the end of the file before any write operation is performed. Therefore, existing data cannot be overwritten.
当使用“a”访问类型或“a+”访问类型打开文件时,所有写操作都发生在文件的末尾。文件指针可以通过使用fseek或rewind函数重新定位,但在执行任何的写操作之前,文件指针总是会自动移回至文件的末尾。因此,原来已有的数据不能被覆盖。
2."a"和"a+"模式有什么区别,又如何选择?
The "a"
mode does not remove the EOF marker before it appends to the file. After appending has occurred, the MS-DOS TYPE command only shows data up to the original EOF marker and not any data appended to the file. Before it appends to the file, the "a+"
mode does remove the EOF marker. After appending, the MS-DOS TYPE command shows all data in the file. The "a+"
mode is required for appending to a stream file that is terminated with the CTRL+Z EOF marker.
“a”模式在添加新数据到文件时不会删除EOF标记。执行附加的操作后,MS-DOS类型命令只显示到原来EOF标记的数据,而不显示刚附加到文件的任何新数据。在添加新数据到文件之前,“a+”模式会删除EOF标记。在执行附加操作后,MS-DOS类型命令显示文件中的所有数据。当进行附加操作时,若当前正在进行操作的文件需要用CTRL+Z或者说是用EOF符标记终止时,需要使用“a+”模式。
3.当指定“r+”、“w+”或“a+”访问类型后,若从读操作切换到写操作,或者从写入操作切换到读取操作时,需要注意什么?
When the "r+"
, "w+"
, or "a+"
access type is specified, both reading and writing are enabled (the file is said to be open for "update"). However, when you switch from reading to writing, the input operation must encounter an EOF marker. If there is no EOF, you must u either or se an intervening call to a file positioning function. The file positioning functions are fsetpos
, fseek
, and rewind
. When you switch from writing to reading, you must use an intervening call to either fflush
or to a file positioning function.
当指定“r+”、“w+”或“a+”访问类型时,将启用读写(即该文件打开是用于“更新”的)。但是,当您从读操作切换到写操作时,输入操作必须遇到EOF标记。如果没有EOF,则必须进行插入一个获取文件位置函数的调用。文件定位函数有fsetpos、fseek和rewind。当您从写入转换到读取时,必须进行插入一个fflush函数的调用或者插入一个获取文件位置函数的调用(在进行插入调用时两者只能选择一个)。
另外除了以上列出的常见的字符串外本文最后还有一些不常用的字符,读者若有兴趣可以下滑参考一下。
下面是这 18种mode的简单测试:
#include<stdlib.h>
#include<stdio.h>
int main()
{
FILE*fp;
///1."r"
///以只读的方式打开文件,该文件必须存在。此操作只能读取数据。
puts("1.\"r\"");
puts("正在以只读的方式打开文件file01.txt");
fp=fopen("D:\\file01.txt","r");
if(fp==NULL)
{
printf("无法打开file01.txt!\n");
}
fclose(fp);
/*
fclose有两个作用:
1. 将输出缓冲区内容写到存储设备上
2. 释放对应的资源
如果不调用fclose,相应地,可能会造成
1. 对文件的更改没有被记录到磁盘上
2. 其他进程无法存取该文件
中的一种或者多种后果。因此对应fopen地调用fclose是必要的
*/
///2."w"
///以只写的方式打开一个空文件,若文件存在则长度清为 0,即该文件内容消失,若不存在则创建该文件。此操作只能写入数据。
puts("\n2.\"w\"");
puts("正在以只写的方式打开一个空文件file02.txt");
fp=fopen("D:\\file02.txt","w");
if(fp==NULL)
{
printf("无法打开file02.txt!\n");
}
fclose(fp);
///3."a"
///以附加的方式打开只写文件,用于在文件尾添写新数据。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,
///即文件原先的内容会被保留,在写入新数据时原来的EOF 符将不会被删除。此操作只能在文件尾添写新数据。
puts("\n3.\"a\"");
puts("以附加的方式打开只写文件file03.txt,用于在文件尾添写新数据。");
fp=fopen("D:\\file03.txt","a");
if(fp==NULL)
{
printf("无法打开file03.txt!\n");
}
fclose(fp);
///4."r+"
///以读/写的方式打开文件,该文件必须存在。此操作可以读取或写入数据。
puts("\n4.\"r+\"");
puts("正在以读/写的方式打开文件file04.txt");
fp=fopen("D:\\file04.txt","r+");
if(fp==NULL)
{
printf("无法打开file04.txt!\n");
}
fclose(fp);
///5."w+"
///以读/写的方式打开一个空文件,若文件存在则长度清为 0,即该文件内容消失,若不存在则创建该文件。此操作可以读取或写入数据。
puts("\n5.\"w+\"");
puts("正在以读/写的方式打开一个空文件file05.txt");
fp=fopen("D:\\file05.txt","w+");
if(fp==NULL)
{
printf("无法打开file05.txt!\n");
}
fclose(fp);
///6."a+"
///以附加的方式打开可读/写的文件,用于读取数据和在文件尾添写新数据。若文件不存在,则会建立该文件,如果文件存在,则写入的数据会被加到文件尾后,
///即文件原先的内容会被保留,在写入新数据时原来的 EOF 符将会被删除。此操作可以读取数据和在文件尾添写新数据。
puts("\n6.\"a+\"");
puts("正在以附加的方式打开可读/写的文件file06.txt,用于读取数据和在文件尾添写新数据。");
fp=fopen("D:\\file06.txt","a+");
if(fp==NULL)
{
printf("无法打开file06.txt!\n");
}
fclose(fp);
///7."rt"
///以只读的方式打开一个文本文件(默认方式,和"r"相同),该文件必须存在。此操作只能读取数据。
puts("\n7.\"rt\"");
puts("正在以只读的方式打开一个文本文件file07.txt");
fp=fopen("D:\\file07.txt","rt");
if(fp==NULL)
{
printf("无法打开file07.txt!\n");
}
fclose(fp);
///8."wt"
///以只写的方式打开一个空的文本文件(默认方式,和"w"相同),若文件存在则长度清为 0,即该文件内容消失,若不存在则创建该文件。此操作只能写入数据。
puts("\n8.\"wt\"");
puts("正在以只写的方式打开一个空的文本文件file08.txt");
fp=fopen("D:\\file08.txt","wt");
if(fp==NULL)
{
printf("无法打开file08.txt!\n");
}
fclose(fp);
///9."at"
///以附加的方式打开一个只写的文本文件,用于在文件尾添写新数据(默认方式,和"a"相同)。若文件不存在,则会建立该文件,如果文件存在,
///写入的数据会被加到文件尾,即文件原先的内容会被保留,在写入新数据时原来的EOF 符将不会被删除。此操作只能在文件尾添写新数据。
puts("\n9.\"at\"");
puts("正在以附加的方式打开一个只写的文本文件file09.txt,用于在文件尾添写新数据。");
fp=fopen("D:\\file09.txt","at");
if(fp==NULL)
{
printf("无法打开file09.txt!\n");
}
fclose(fp);
///10."rb"
///以只读的方式打开一个二进制文件(非默认方式,若不加"b",则默认打开的是一个文本文件),该文件必须存在。此操作只能读取数据。
puts("\n10.\"rb\"");
puts("正在以只读的方式打开一个二进制文件file10.txt");
fp=fopen("D:\\file10.txt","rb");
if(fp==NULL)
{
printf("无法打开file10.txt!\n");
}
fclose(fp);
///11."wb"
///以只写的方式打开一个空的二进制文件(非默认方式,若不加"b",则默认打开的是一个文本文件),
///若文件存在则长度清为 0,即该文件内容消失,若不存在则创建该文件。此操作只能写入数据。
puts("\n11.\"wb\"");
puts("正在以只写的方式打开一个空的二进制文件file11.txt");
fp=fopen("D:\\file11.txt","wb");
if(fp==NULL)
{
printf("无法打开file11.txt!\n");
}
fclose(fp);
///12."ab"
///以附加的方式打开一个只写的二进制文件,用于在文件尾添写新数据(非默认方式,若不加"b",则默认打开的是一个文本文件)。若文件不存在,则会建立该文件,
///如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留,在写入新数据时原来的EOF 符将不会被删除。此操作只能在文件尾添写新数据。
puts("\n12.\"ab\"");
puts("正在以附加的方式打开一个只写的二进制文件file12.txt,用于在文件尾添写新数据。");
fp=fopen("D:\\file12.txt","ab");
if(fp==NULL)
{
printf("无法打开file12.txt!\n");
}
fclose(fp);
///13."rt+"
///以读/写的方式打开一个文本文件(默认方式,和"r+"相同),该文件必须存在。此操作可以读取或写入数据。
puts("\n13.\"rt+\"");
puts("正在以读/写的方式打开一个文本文件file13.txt");
fp=fopen("D:\\file13.txt","rt+");
if(fp==NULL)
{
printf("无法打开file13.txt!\n");
}
fclose(fp);
///14."wt+"
///以读/写的方式打开一个空的文本文件(默认方式,和"w+"相同),若文件存在则长度清为 0,即该文件内容消失,若不存在则创建该文件。此操作可以读取或写入数据。
puts("\n14.\"wt+\"");
puts("正在以读/写的方式打开一个空的文本文件file14.txt");
fp=fopen("D:\\file14.txt","wt+");
if(fp==NULL)
{
printf("无法打开file14.txt!\n");
}
fclose(fp);
///15."at+"
///以附加的方式打开可读/写的一个文本文件,用于读取数据和在文件尾添写新数据(默认方式,和"a+"相同)。若文件不存在,则会建立该文件,如果文件存在,则写入的数据会被加到文件尾后,
///即文件原先的内容会被保留,在写入新数据时原来的 EOF 符将会被删除。此操作可以读取数据和在文件尾添写新数据。
puts("\n15.\"at+\"");
puts("正在以附加的方式打开可读/写的一个文本文件file15.txt,用于读取数据和在文件尾添写新数据。");
fp=fopen("D:\\file15.txt","at+");
if(fp==NULL)
{
printf("无法打开file15.txt!\n");
}
fclose(fp);
///16."rb+"
///以读/写的方式打开一个二进制文件(非默认方式,若不加"b",则默认打开的是一个文本文件),该文件必须存在。此操作可以读取或写入数据。
puts("\n16.\"rb+\"");
puts("正在以读/写的方式打开一个二进制文件file16.txt");
fp=fopen("D:\\file16.txt","rb+");
if(fp==NULL)
{
printf("无法打开file16.txt!\n");
}
fclose(fp);
///17."wb+"
///以读/写的方式打开一个空的二进制文件(非默认方式,若不加"b",则默认打开的是一个文本文件),若文件存在则长度清为 0,
///即该文件内容消失,若不存在则创建该文件。此操作可以读取或写入数据。
puts("\n17.\"wb+\"");
puts("正在以读/写的方式打开一个空的二进制文件file17.txt");
fp=fopen("D:\\file17.txt","wb+");
if(fp==NULL)
{
printf("无法打开file17.txt!\n");
}
fclose(fp);
///18."ab+"
///以附加的方式打开一个可读/写的二进制文件,用于读取数据和在文件尾添写新数据(非默认方式,若不加"b",则默认打开的是一个文本文件)。若文件不存在,则会建立该文件,
///如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留,在写入新数据时原来的 EOF 符将会被删除。此操作可以读取数据和在文件尾添写新数据。
puts("\n18.\"ab+\"");
puts("正在以附加的方式打开一个可读/写的二进制文件file18.txt,用于读取数据和在文件尾添写新数据。");
fp=fopen("D:\\file18.txt","ab+");
if(fp==NULL)
{
printf("Can not open file18.txt!\n");
}
fclose(fp);
return 0;
}
除了以上列出的常见的字符串外还有一些不常用的字符,读者若有兴趣可以参考:
In addition to the earlier values, the following characters can be appended to mode
to specify the translation mode for newline characters.
t
Open in text (translated) mode. In this mode, CTRL+Z is interpreted as an EOF character on input. In files that are opened for reading/writing by using"a+"
, fopen
checks for a CTRL+Z at the end of the file and removes it, if it is possible. This is done because using fseek
and ftell
to move within a file that ends with CTRL+Z may cause fseek
to behave incorrectly near the end of the file.
In text mode, carriage return–linefeed combinations are translated into single linefeeds on input, and linefeed characters are translated to carriage return–linefeed combinations on output. When a Unicode stream-I/O function operates in text mode (the default), the source or destination stream is assumed to be a sequence of multibyte characters. Therefore, the Unicode stream-input functions convert multibyte characters to wide characters (as if by a call to the mbtowc
function). For the same reason, the Unicode stream-output functions convert wide characters to multibyte characters (as if by a call to the wctomb
function).
b
Open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed.
If t
or b
is not given in mode
, the default translation mode is defined by the global variable _fmode. If t
or b
is prefixed to the argument, the function fails and returns NULL
.
For more information about how to use text and binary modes in Unicode and multibyte stream-I/O, see Text and Binary Mode File I/O and Unicode Stream I/O in Text and Binary Modes.
c
Enable the commit flag for the associated filename
so that the contents of the file buffer are written directly to disk if either fflush
or _flushall
is called.
n
Reset the commit flag for the associated filename
to "no-commit." This is the default. It also overrides the global commit flag if you link your program with COMMODE.OBJ. The global commit flag default is "no-commit" unless you explicitly link your program with COMMODE.OBJ (see Link Options).
N
Specifies that the file is not inherited by child processes.
S
Specifies that caching is optimized for, but not restricted to, sequential access from disk.
R
Specifies that caching is optimized for, but not restricted to, random access from disk.
T
Specifies a file as temporary. If possible, it is not flushed to disk.
D
Specifies a file as temporary. It is deleted when the last file pointer is closed.
ccs=ENCODING
Specifies the coded character set to use (UTF-8
, UTF-16LE
, or UNICODE
) for this file. Leave unspecified if you want ANSI encoding.