fopen、_wfopen(转)

80 篇文章 2 订阅
25 篇文章 0 订阅

打开文件。 这些执行附加参数验证并返回错误代码的函数有更安全的版本可用;请参阅 fopen_s、_wfopen_s

语法

C复制

FILE *fopen(
   const char *filename,
   const char *mode
);
FILE *_wfopen(
   const wchar_t *filename,
   const wchar_t *mode
);

参数

filename
文件名。

模式
启用的访问类型。

返回值

这些函数均返回指向打开文件的指针。 一个 null 指针值指示错误。 如果文件名模式NULL或空字符串,这些函数则会触发无效参数处理程序中, 所述参数验证。 如果允许执行继续,这些函数将返回NULL并设置errnoEINVAL

有关详细信息,请参阅 errno、_doserrno、_sys_errlist 和 _sys_nerr

备注

Fopen函数将打开由指定的文件filename。 默认情况下,窄文件名使用 ANSI 代码页 (CP_ACP) 解释字符串。 在 Windows 桌面应用程序中,可以通过使用 SetFileApisToOEM 函数将此更改为 OEM 代码页 (CP_OEMCP)。 可以使用AreFileApisANSI函数来确定是否filename使用 ANSI 还是系统默认 OEM 代码页解释。 _wfopen是宽字符版本fopen; 的自变量 _wfopen都是宽字符字符串。 否则为 _wfopenfopen行为方式相同。 只需使用 _wfopen不会影响文件流中使用的编码的字符集。

fopen接受在执行; 时在文件系统上有效的路径fopen接受 UNC 路径和涉及的路径映射的网络驱动器,只要执行代码的系统有权访问该共享或映射驱动器,在执行时。 构造路径时fopen,请确保驱动器、 路径或网络共享将执行环境中可用。 可使用斜杠 (/) 或反斜杠 (\) 作为路径中的目录分隔符。

对文件执行任何其他操作前,请始终检查返回值以确定指针是否为 NULL。 如果发生错误,全局变量errno设置并可用于获取特定错误信息。 有关详细信息,请参阅 errno、_doserrno、_sys_errlist 和 _sys_nerr

Unicode 支持

fopen支持 Unicode 文件流。 若要打开 Unicode 文件,请将传递ccs指定为所需的编码的标志fopen,按如下所示。

FILE *fp = fopen("newfile.txt", "rt+, ccs=encoding");

允许的值为编码UNICODE, utf-8,以及UTF 16LE

输入的函数时在 Unicode 模式下打开文件,将数据从文件读取到 utf-16 数据存储为类型转换wchar_t。 写入到在 Unicode 模式下打开的文件的函数要求包含存储为类型的 utf-16 数据的缓冲区wchar_t。 如果将文件编码为 UTF-8,则在写入它时,UTF-16 数据会转换为 UTF-8;在读取它时,该文件的 UTF-8 编码的内容会转换为 UTF-16。 尝试在 Unicode 模式下读取或写入奇数个字节会导致 参数验证 错误。 若要读取或写入在你的程序中存储为 UTF-8 的数据,请使用文本或二进制文件模式,而不是 Unicode 模式。 你应负责所有必需的编码转换。

如果文件已存在并已打开以进行读取或追加,字节顺序标记 (BOM)(如果文件中有)将确定编码。 BOM 编码优先的编码指定的ccs标志。 Ccs编码时,才使用没有 BOM 或文件是新文件。

 备注

BOM 检测仅适用于在 Unicode 模式下打开的文件 (即,通过传递ccs标志)。

下表总结了用于各种模式ccs识别分配给标志fopen和文件中的字节顺序标记。

基于 ccs 标志和 BOM 使用的编码

ccs 标志无 BOM(或新文件)物料清单:UTF-8物料清单:UTF-16
UNICODEUTF-16LEUTF-8UTF-16LE
UTF-8UTF-8UTF-8UTF-16LE
UTF-16LEUTF-16LEUTF-8UTF-16LE

在 Unicode 模式下打开以进行写入的文件将自动写入 BOM。

如果模式下是 ",ccs =编码", fopen首先尝试使用这两个读取打开的文件和写入访问权限。 如果成功,此函数将读取 BOM 以确定文件的编码;如果失败,此函数将使用文件的默认编码。 在任一情况下, fopen将然后重新打开该文件使用只写访问权限。 (这适用于 "a" 模式下唯一的不适用于 "a +" 模式。)

一般文本例程映射

TCHAR.H 例程未定义 _UNICODE 和 _MBCS已定义 _MBCS已定义 _UNICODE
_tfopenfopenfopen_wfopen

字符字符串模式下指定类型的访问请求时,对于文件,请按如下所示。

模式Access
“r”打开以便读取。 如果文件不存在或无法找到fopen调用失败。
“w”打开用于写入的空文件。 如果给定文件存在,则其内容会被销毁。
“a”在文件末尾打开以进行写入(追加),在新数据写入到文件之前不移除文件末尾 (EOF) 标记。 创建文件(如果文件不存在)。
“r+”打开以便读取和写入。 文件必须存在。
“w+”打开用于读取和写入的空文件。 如果文件存在,则其内容会被销毁。
“a+”打开以进行读取和追加。 追加操作包括在新数据写入文件之前移除 EOF 标记。 写入完成后,EOF 标记不会还原。 创建文件(如果文件不存在)。

通过打开文件时 "a" 访问类型或 "a +" 访问类型,所有写入操作可能出现在文件末尾。 通过使用可重新定位文件指针fseekrewind,但将始终被移回文件末尾任何写入操作执行前。 因此,无法覆盖现有数据。

"A" 模式不会删除 EOF 标记追加到文件之前。 在追加后,MS-DOS TYPE 命令只显示原始 EOF 标记之前的数据,不显示追加到文件的任何数据。 它将追加到文件,才能 "a +" 模式会删除 EOF 标记。 在追加后,MS-DOS TYPE 命令显示文件中的所有数据。 "A +" 模式是所必需的追加到使用 CTRL + Z EOF 标记终止的流文件。

当 "r +", "w +",或 "a +" 指定访问类型时,启用了读取和写入 (文件将状态以执行"更新"处于打开状态)。 但是,当你从读取切换到写入时,输入操作必须遇到 EOF 标记。 如果没有 EOF,必须使用对文件定位函数的干预调用。 文件定位函数是fsetpos, fseek,并后退。 当您从写入切换到读取时,必须使用为的干预调用fflush或文件定位函数。

除了前面的值,可以将以下字符追加到模式下以指定换行符的转换模式。

模式修饰符转换模式
t在文本(转换)模式下打开。
b在二进制(未转换)模式下打开;不进行涉及回车和换行字符的转换。

在文本模式下,CTRL + Z 解释为 EOF 字符在输入。 在打开使用读取/写入的文件中 "a +", fopen检查文件末尾的 CTRL + Z 并移除它,如有可能。 这是因为使用fseekftell CTRL + Z 结尾可能会导致文件内移动fseek文件末尾附近错误运行。

在文本模式下,回车-换行组合将转换为单一的换行输入,并换行字符转换为输出回车-换行组合。 当 Unicode 流 I/O 函数在文本模式(默认设置)下运行时,源或目标流将假定为一系列多字节字符。 因此,Unicode 流输入函数将多字节字符转换为宽字符(就像调用 mbtowc 函数一样)。 出于同一原因,Unicode 流输出函数将宽字符转换为多字节字符(就像调用 wctomb 函数一样)。

如果tb中未给模式,则默认转换模式由全局变量_fmode。 如果tb自变量、 函数将失败并返回到前缀NULL

有关如何在 Unicode 和多字节流 I/O 中使用文本和二进制模式的详细信息,请参阅 Text and Binary Mode File I/O 和 文本和二进制模式下的 Unicode 流 I/O

以下选项可以追加到模式下来指定其他行为。

模式修饰符行为
c启用关联的提交标志文件名,以便文件缓冲区的内容直接写入磁盘fflush或 _flushall调用。
n重置为关联的提交标志文件名到"不提交。" 这是默认设置。 如果将程序显式链接到 COMMODE.OBJ,它还将重写全局提交标志。 除非将程序显式链接到 COMMODE.OBJ,否则全局提交标志默认为“no-commit”(请参阅 Link Options)。
N指定文件不由子进程继承。
S指定缓存针对(但不限于)从磁盘的顺序访问进行优化。
R指定缓存针对(但不限于)从磁盘的随机访问进行优化。
T将文件指定为临时。 如果可能,它不会刷新到磁盘。
D将文件指定为临时。 最后一个文件指针关闭时,它将被删除。
ccs=encoding指定设置为使用的编码的字符 (之一utf-8, UTF 16LE,或UNICODE) 此文件。 如果需要 ANSI 编码,请不要指定此字符集。

有效字符模式下在中使用字符串fopen并 _fdopen对应于oflag 中使用的参数_open_sopen,按如下所示。

中的字符模式下字符串等效oflag值_打开 /_sopen
a_O_WRONLY | _O_APPEND (usually _O_WRONLY | _O_CREAT | _O_APPEND)
a+_O_RDWR | _O_APPEND (usually _O_RDWR | _O_APPEND | _O_CREAT )
r_O_RDONLY
r+_O_RDWR
w_O_WRONLY (usually _O_WRONLY | _O_CREAT | _O_TRUNC)
w+_O_RDWR (usually _O_RDWR | _O_CREAT | _O_TRUNC)
b_O_BINARY
t_O_TEXT
c
n
S_O_顺序
R_O_RANDOM
T_O_SHORTLIVED
D_O_临时
ccs=UNICODE_O_WTEXT
ccs=UTF-8_O_UTF8
ccs=UTF-16LE_O_UTF16

如果使用的rb模式下,您无需移植代码,并且如果您希望读取大文件中的大多数或不关心网络性能,您还可以考虑是否使用内存映射的 Win32 文件作为一个选项。

要求

函数必需的标头
fopen<stdio.h>
_wfopen<stdio.h> 或 <wchar.h>

_wfopen是 Microsoft 扩展。 有关兼容性的更多信息,请参见 兼容性

C, n, t, S, R, T,和D 模式选项是 Microsoft 扩展fopen并 _fdopen ,不应在需要 ANSI 可移植性时使用。

示例 1

以下程序打开两个文件。 它使用fclose以关闭第一个文件并 _fcloseall关闭所有剩余文件。

C复制

// 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 );
}

Output复制

The file 'crt_fopen.c' was opened
The file 'data2' was opened
Number of files closed by _fcloseall: 1

示例 2

以下程序在具有 Unicode 编码的文本模式下创建文件(或在文件存在时覆盖文件)。 然后,它将两个字符串写入文件并关闭文件。 输出是名为 _wfopen_test.xml 的文件,其中包含输出部分中的数据。

C复制

// 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;
}

请参阅

流 I/O
多字节字符序列的解释
fclose、_fcloseall
_fdopen、_wfdopen
ferror
_fileno
freopen、_wfreopen
_open、_wopen
_setmode
_sopen、_wsopen

转:fopen、_wfopen | Microsoft Docs

fopen, _wfopen | Microsoft Docs

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值