打开文件。 提供这些函数的更多安全版本;请参见 fopen_s、_wfopen_s。
FILE *fopen( const char *filename, const char *mode ); FILE *_wfopen( const wchar_t *filename, const wchar_t *mode );
这些函数均返回指向打开文件的指针。 一个 null 指针值指示错误。 如果 filename 或 mode 为 NULL 或空字符串,这些函数将触发无效参数处理程序(如参数验证所述)。 如果允许执行继续,则这些函数返回 NULL 并将 errno 设置为 EINVAL。
有关更多信息,请参见 errno、_doserrno、_sys_errlist 和 _sys_nerr。
fopen 函数打开 filename 指定的文件。 _wfopen 是 fopen 的宽字符版本;_wfopen 的参数是宽字符串。 除此以外,_wfopen 和 fopen 的行为完全相同。 仅使用 _wfopen 不会影响在文件流中使用的编码字符集。
fopen 接受执行时在文件系统上有效的路径;fopen 还接受 UNC 路径和包含映射的网络驱动器的路径(前提是执行代码的系统在执行时能够访问共享或映射的驱动器)。 为 fopen 构造路径时,请确保驱动器、路径或网络共享在执行环境中可用。 可使用斜杠 (/) 或反斜杠 (\) 作为路径中的目录分隔符。
对文件执行任何进一步操作前,请始终检查返回值以确定指针是否为 NULL。 如果发生错误,系统将设置全局变量 errno,此变量可用于获取特定错误信息。 有关更多信息,请参见 errno、_doserrno、_sys_errlist 和 _sys_nerr。
Unicode 支持
fopen 支持 Unicode 文件流。 若要打开 Unicode 文件,请将指定所需编码的 ccs 标志传递到 fopen,如下所示。
fopen(&fp, "newfile.txt", "rt+, ccs= encoding ");
允许使用的 encoding 值为 UNICODE、UTF-8 和 UTF-16LE。
如果文件已存在并已打开以进行读取或追加,字节顺序标记 (BOM)(如果文件中有)将确定编码。 BOM 编码优先于 ccs 标志指定的编码。 只有在没有 BOM 或文件是新文件时,才使用 ccs 编码。
说明 |
---|
BOM 检测仅适用于在 Unicode 模式下(即通过传递 ccs 标志)打开的文件。 |
下表汇总的模式用于传递到文件中的 fopen 和字节顺序标记的各种 ccs 标志。
ccs 标志 | 无 BOM(或新文件) | BOM:UTF-8 | BOM:UTF-16 |
---|---|---|---|
UNICODE | UTF-16LE | UTF-8 | UTF-16LE |
UTF-8 | UTF-8 | UTF-8 | UTF-16LE |
UTF-16LE | UTF-16LE | UTF-8 | UTF-16LE |
在 Unicode 模式下打开以进行写入的文件将自动写入 BOM。
如果 mode 为“a, ccs=<encoding>”,fopen 将先尝试使用读取和写入访问权限打开文件。 如果成功,此函数将读取 BOM 以确定文件的编码;如果失败,此函数将使用文件的默认编码。 无论何种情况,fopen 随后均将通过只写访问权限打开文件。(这仅适用于 a 模式,不适用于 a+ 模式。)
TCHAR.H 例程 | 未定义的 _UNICODE 和 _MBCS | 已定义 _MBCS | 已定义 _UNICODE |
---|---|---|---|
_tfopen | fopen | fopen | _wfopen |
字符串 mode 指定为文件请求的访问类型,如下所示。
使用 "a" 访问类型或 "a+" 访问类型打开文件时,所有写入操作均将在文件末尾进行。 使用 fseek 或 rewind 可重新定位文件指针,但在执行任何写入操作前,文件指针将始终被移回文件末尾。 因此,无法覆盖现有数据。
在 EOF 标记追加到文件之前,"a" 模式不会将其移除。 在追加后,MS-DOS TYPE 命令只显示原始 EOF 标记之前的数据,不显示追加到文件的任何数据。 EOF 标记追加到文件之前,"a+" 模式不会将其移除。 在追加后,MS-DOS TYPE 命令显示文件中的所有数据。 需使用 "a+" 模式才能附加到通过 CTRL+Z EOF 标记终止的流文件。
指定 "r+"、"w+" 或 "a+" 访问类型时,允许读取和写入(文件将处于打开状态以进行“更新”)。 但是,当你从读取切换到写入时,输入操作必须遇到 EOF 标记。 如果没有 EOF,必须使用对文件定位函数的干预调用。 文件定位函数是 fsetpos、fseek 和 rewind。 从写入切换到读取时,必须使用对 fflush 或文件定位函数的干预调用。
除了前面的值以外,可将以下字符追加到 mode 以指定换行符的转换模式。
在文本模式下,输入时,回车-换行组合将转换为单一的换行,输出时,换行字符将转换为回车-换行组合。 当 Unicode 流 I/O 函数在文本模式(默认设置)下运行时,源或目标流将假定为一系列多字节字符。 因此,Unicode 流输入函数将多字节字符转换为宽字符(就像调用 mbtowc 函数一样)。 出于同一原因,Unicode 流输出函数将宽字符转换为多字节字符(就像调用 wctomb 函数一样)。
如果 t 或 b 在 mode 中未给出,则默认转换模式由全局变量 _fmode 定义。 如果 t 或 b 是该参数的前缀,则函数将失败并返回 NULL。
有关如何在 Unicode 和多字节流 I/O 中使用文本和二进制模式的更多信息,请参见文本和二进制模式文件 I/O 和 文本和二进制模式下的 Unicode 流 I/O。
在 fopen 和 _fdopen 中使用的 mode 字符串的有效字符对应于在 _open 和 _sopen 中使用的 oflag 参数。
模式字符串中的字符 | _open /_sopen 的等效 oflag 值。 |
---|---|
a | _O_WRONLY | _O_APPEND (通常为 _O_WRONLY | _O_CREAT | _O_APPEND) |
a+ | _O_RDWR | _O_APPEND (通常为 _O_RDWR | _O_APPEND | _O_CREAT ) |
r | _O_RDONLY |
r+ | _O_RDWR |
w | _O_WRONLY (通常为 _O_WRONLY | _O_CREAT | _O_TRUNC) |
w+ | _O_RDWR (通常为 _O_RDWR | _O_CREAT | _O_TRUNC) |
b | _O_BINARY |
t | _O_TEXT |
c | 无 |
n | 无 |
S | _O_SEQUENTIAL |
R | _O_RANDOM |
T | _O_SHORTLIVED |
D | _O_TEMPORARY |
ccs=UNICODE | _O_WTEXT |
ccs=UTF-8 | _O_UTF8 |
ccs=UTF-16LE | _O_UTF16 |
如果你使用 rb 模式、不必移植代码、希望读取大文件中的大部分内容或不担心网络性能,你可能还要考虑是否使用内存映射的 Win32 文件方式。
函数 | 必需的标头 |
---|---|
fopen | <stdio.h> |
_wfopen | <stdio.h> 或 <wchar.h> |
有关兼容性的更多信息,请参见兼容性。
c 、n、t、S、R、T 和 Dmode 选项是 fopen 和 _fdopen 的 Microsoft 扩展,不应在需要 ANSI 可移植性时使用。
以下程序打开两个文件。它使用 fclose 关闭第一个文件,使用 _fcloseall 关闭所有剩余文件。
// crt_fopen.c // compile with: /W3 // This program opens two files. It uses // fclose to close the first file and // _fcloseall to close all remaining files. #include <stdio.h> FILE *stream, *stream2; int main( void ) { int numclosed; // Open for read (will fail if file "crt_fopen.c" does not exist) if( (stream = fopen( "crt_fopen.c", "r" )) == NULL ) // C4996 // Note: fopen is deprecated; consider using fopen_s instead printf( "The file 'crt_fopen.c' was not opened\n" ); else printf( "The file 'crt_fopen.c' was opened\n" ); // Open for write if( (stream2 = fopen( "data2", "w+" )) == NULL ) // C4996 printf( "The file 'data2' was not opened\n" ); else printf( "The file 'data2' was opened\n" ); // Close stream if it is not NULL if( stream) { if ( fclose( stream ) ) { printf( "The file 'crt_fopen.c' was not closed\n" ); } } // All other files are closed: numclosed = _fcloseall( ); printf( "Number of files closed by _fcloseall: %u\n", numclosed ); }
<span id="mt112" class="sentence" data-guid="36160afb7487ebf03eb3d7b8c058e6e0" data-source="" the="" file="" 'crt_fopen.c'="" was="" opened"="" xml:space="preserve">文件“crt_fopen.c”已打开 文件“data2”已打开 由 _fcloseall 所关闭的文件数量为:1
以下程序在具有 Unicode 编码的文本模式下创建文件(或在文件存在时覆盖文件)。然后,它将两个字符串写入文件并关闭文件。 输出是名为 _wfopen_test.xml 的文件,其中包含输出部分中的数据。
// crt__wfopen.c // compile with: /W3 // This program creates a file (or overwrites one if // it exists), in text mode using Unicode encoding. // It then writes two strings into the file // and then closes the file. #include <stdio.h> #include <stddef.h> #include <stdlib.h> #include <wchar.h> #define BUFFER_SIZE 50 int main(int argc, char** argv) { wchar_t str[BUFFER_SIZE]; size_t strSize; FILE* fileHandle; // Create an the xml file in text and Unicode encoding mode. if ((fileHandle = _wfopen( L"_wfopen_test.xml",L"wt+,ccs=UNICODE")) == NULL) // C4996 // Note: _wfopen is deprecated; consider using _wfopen_s instead { wprintf(L"_wfopen failed!\n"); return(0); } // Write a string into the file. wcscpy_s(str, sizeof(str)/sizeof(wchar_t), L"<xmlTag>\n"); strSize = wcslen(str); if (fwrite(str, sizeof(wchar_t), strSize, fileHandle) != strSize) { wprintf(L"fwrite failed!\n"); } // Write a string into the file. wcscpy_s(str, sizeof(str)/sizeof(wchar_t), L"</xmlTag>"); strSize = wcslen(str); if (fwrite(str, sizeof(wchar_t), strSize, fileHandle) != strSize) { wprintf(L"fwrite failed!\n"); } // Close the file. if (fclose(fileHandle)) { wprintf(L"fclose failed!\n"); } return 0; }