1fopen_s 函数原型编辑
fopen_s,_wfopen_s
打开一个文件,这些版本比fopen,_wfopen在安全性上都有增强。
使用方法:
---------------------------------------------------
errno_t fopen_s( FILE** pFile, const char *filename, const char *mode );
errno_t _wfopen_s( FILE** pFile, const wchar_t *filename, const wchar_t *mode );
---------------------------------------------------
2函数参数和返回值编辑
outpFile
文件指针将接收到打开的文件指针指向的指针。
infilename
文件名。
inmode
允许的访问类型。
---------------------------------------------------
返回值:
如果成功返回0,失败则返回相应的错误代码。
错误代码请到_doserrno,errno, _sys_errlist, and _sys_nerr去了解更多
错误条件
pFile | filename | mode | 返回值 | pFile的内容 |
NULL | 任何 | 任何 | EINVAL | 没有改变 |
任何 | NULL | 任何 | EINVAL | 没有改变 |
任何 | 任何 | NULL | EINVAL | 没有改变 |
EINVAL:无效的参数。
3备注:编辑
通过打开的文件fopen_s和_wfopen_s不是可共享。如果您需要先设置为可共享一个文件,则使用_fsopen、_wfsopen与适当的共享模式常量 — — 例如,_SH_DENYNO为读/写的共享。
fopen_s函数打开的文件指定的filename._wfopen_s是宽字符版本的fopen_s; 参数与_wfopen_s是宽字符字符串。_wfopen_s和fopen_s的行为相同 ; 否则。
fopen_s可以接受的有效执行 ; 在文件系统上的路径 UNC 路径和涉及到映射的网络驱动器的路径所接受的fopen_s,只要正在执行代码的系统有权访问该共享,或在执行时映射的网络驱动器。当构造路径fopen_s、 不要臆测可用性驱动器、 路径或网络共享的执行环境中。您可以使用正斜杠 (/) 或反斜杠 (\),作为路径中的目录分隔符。
这些函数将验证它们的参数。如果pFile,filename,或mode为 null 的指针,这些函数生成无效参数异常,如中所述参数验证.
检查返回值,是否函数成功执行该文件的任何进一步操作之前,请参阅。如果发生错误,则返回的错误代码和全局变量errno设置。有关详细信息,请参阅errno、_doserrno、_sys_errlist 和 _sys_nerr.
Unicode 支持
fopen_s支持 Unicode 的文件流。若要打开新的或现有的 Unicode 文件,请传递ccs标志,它指定所需的编码为fopen_s::
fopen_s(&fp, "newfile.txt", "rw,ccs=encoding");
允许的值encoding的UNICODE,UTF-8,和UTF-16LE.如果存在未指定值的encoding,fopen_s使用 ANSI 编码。
如果该文件已经存在,并且已打开以进行读取或追加,字节顺序标记 (BOM),如果存在于文件中,将确定的编码。物料清单编码优先通过编码由ccs标志。ccs没有物料清单时存在,或如果该文件是新文件只使用编码。
4文件访问方式编辑
"r"
打开以进行读取。如果该文件不存在,或无法找到,fopen_s调用失败。
"w"
打开一个空文件以进行写入。如果该文件存在,其内容将被销毁。
"a"
打开以进行写入 (追加) 而不将新数据写入文件之前删除的 EOF 标记文件的末尾。如果它不存在,则创建该文件。
"r+"
将打开并读取和写入。 (该文件必须存在。
"w+"
打开一个空的文件进行读写。如果该文件存在,其内容将被销毁。
"a+"
将打开并读取文件和追加。追加操作包括删除 EOF 标记的新数据写入到文件并在编写完成后还原 EOF 标记之前。如果它不存在,则创建该文件。
通过打开文件时"a"或"a+"访问类型,所有写操作出现在文件的结尾。可通过使用定位文件指针fseek或rewind,但其始终移回至该文件的末尾之前任何写入,因此无法覆盖现有数据执行操作。
"a"模式下不会追加到该文件之前删除 EOF 标记。追加发生后,MS-DOS TYPE 命令仅显示最原始的 EOF 标记的数据和追加到文件中没有任何数据。"a+"模式不会追加到该文件之前删除的 EOF 标记。后追加,MS-DOS TYPE 命令在文件中显示所有数据。"a+"模式所需的追加到流文件,将终止通过使用 CTRL + Z EOF 标记。
当"r+","w+",或"a+"指定访问类型,允许读取和写入。 (就说是打开"更新"文件)。 但是,当从阅读切换到书写,输入的操作必须会遇到 EOF 标记。如果没有任何 EOF,则必须使用中间文件定位函数调用。文件定位函数是fsetpos,fseek,和rewind.从读数到写切换时,您必须使用中间调用fflush或文件定位函数。
除了上面的值中,下列字符可以包含在mode指定换行字符的转换模式:
t
以文本形式打开 (翻译) 模式。在此模式中,CTRL + Z 被解释为对输入文件结尾字符中。要读取/写入与打开的文件中"a+",fopen_s检查 CTRL + Z 结尾的文件并移除它,如果可能的话。这是因为使用fseek和ftell在结尾为 CTRL + Z,可能会导致文件移动fseek文件末尾附近的不当行为。
此外,在文本模式下,回车 – 换行组合被翻译成在输入时,一个换行符) 和换行符转换为回车 – 换行组合输出上。当 Unicode 流 i/o 函数操作文本模式 (默认值),源或目标流被认为是多字节字符的序列。因此,Unicode 流输入函数将多字节字符转换为宽字符 (如果通过调用mbtowc函数)。出于同样的原因,Unicode 流输出函数将宽字符转换为多字节字符 (如果通过调用wctomb函数)。
b
打开二进制 (未翻译) 模式 ; 翻译涉及回车和换行字符不会显示。
如果t或b中没有给出mode,默认转换模式定义全局变量_fmode。如果t或b将作为参数,函数将失败并返回前缀NULL.
有关使用文本和二进制模式中 Unicode 和多字节流 i/o 的详细信息,请参阅文本和二进制模式文件 I/O和Unicode 文本和二进制模式中的流 I/O。
c
启用提交标记关联的filename,以便文件缓冲区的内容将直接写入磁盘,如果任一fflush或_flushall调用。
n
重置该提交标记关联的filename为"无约束" 这是默认设置。它还重写全局提交标志,如果链接您的程序使用 COMMODE.OBJ。全球提交标志默认设置是"无约束" 除非您显式链接您的程序使用 COMMODE。OBJ (请参阅链接选项)。
N
指定的文件不由子进程继承。
S
指定的缓存优化的但不是限于,顺序访问磁盘。
R
指定的缓存优化的但不是限于,随机访问磁盘。
T
指定临时文件。如有可能,它未被刷新到磁盘。
D
指定临时文件。最后的文件指针被关闭时,它将被删除。
ccs=ENCODING
指定编码的字符集可用于此文件 (utf-8、 UTF-16LE 和 UNICODE)。离开这未指定是否希望 ANSI 编码。
有效的字符mode中使用的字符串fopen_s和_fdopen对应于oflag参数中使用_ 打开和_sopen,如下。
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 |
5示例编辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | //crt_fopen_s.c //Thisprogramopenstwofiles.Ituses //fclosetoclosethefirstfileand //_fclosealltocloseallremainingfiles. #include FILE *stream,*stream2; intmain( void ) { errno_terr; //Openforread(willfailiffile"crt_fopen_s.c"doesnotexist) err=fopen_s(&stream, "crt_fopen_s.c" , "r" ); if (err==0) { printf ( "Thefile'crt_fopen_s.c'wasopened\n" ); } else { printf ( "Thefile'crt_fopen_s.c'wasnotopened\n" ); } //Openforwrite err=fopen_s(&stream2, "data2" , "w+" ); if (err==0) { printf ( "Thefile'data2'wasopened\n" ); } else { printf ( "Thefile'data2'wasnotopened\n" ); } //ClosestreamifitisnotNULL if (stream) { err= fclose (stream); if (err==0) { printf ( "Thefile'crt_fopen_s.c'wasclosed\n" ); } else { printf ( "Thefile'crt_fopen_s.c'wasnotclosed\n" ); } } //Allotherfilesareclosed: intnumclosed=_fcloseall(); printf ( "Numberoffilesclosedby_fcloseall:%u\n" ,numclosed); } |