在上一个问题的模型中,我询问了所谓的安全库折旧,我发现自己同样对于为什么fopen()
应该被弃用感到困惑.
该函数接受两个C字符串,并返回FILE*ptr,或者在失败时返回NULL.线程安全问题/字符串溢出问题在哪里?或者是别的什么?
提前致谢
你可以用fopen()
.说真的,不要在这里注意到微软,他们通过偏离ISO标准让程序员真正受到伤害.他们似乎认为编写代码的人在某种程度上是脑死亡,并且在调用库函数之前不知道如何检查参数.
如果有人不愿意学习C编程的复杂性,他们真的没有做生意.他们应该转向更安全的语言.
这似乎是在厂商锁定由开发商微软只是一个尝试(尽管他们不是唯一的谁尝试一下,所以我没有特别训斥他们).我通常会添加:
#define _CRT_SECURE_NO_WARNINGS
(或"-D"
命令行中的变体)对我的大多数项目来说,确保在编写完全有效的合法C代码时我不会被编译器困扰.
Microsoft在函数中提供了额外的fopen_s()
功能(文件编码,一个)以及更改内容的返回方式.这可能会使Windows程序员更好,但使代码本身不可移植.
如果您只是为Windows编写代码,请务必使用它.我自己更喜欢在任何地方编译和运行我的代码的能力(尽可能少的变化).
从C11开始,这些安全功能现在已成为标准的一部分,尽管是可选的.查看附件K了解详细信息.
有一个官方的ISO/IEC JTC1/SC22/WG14(C语言)技术报告TR24731-1(边界检查接口)及其基本原理:
http://www.open-std.org/jtc1/sc22/wg14
还有针对TR24731-2(动态分配功能)的工作.
陈述的理由fopen_s()
是:
6.5.2文件访问功能
创建文件时,
fopen_s
和freopen_s
函数通过设置文件保护并使用独占访问权限打开文件来保护文件免受未经授权的访问,从而提高安全性.
规范说:
#define __STDC_WANT_LIB_EXT1__ 1 #includeerrno_t fopen_s(FILE * restrict * restrict streamptr, const char * restrict filename, const char * restrict mode);
没有streamptr
,filename
或mode
将是一个空指针.
如果存在运行时约束冲突,fopen_s
则不会尝试打开文件.此外,如果streamptr
不是空指针,则fopen_s
设置*streamptr
为空指针.
该
fopen_s
函数打开名称为其所指向的字符串的文件filename
,并将流与其关联.模式字符串应如所描述的那样
fopen
,另外,以字符"w"或"a"开头的模式可以在字符"u"之后,见下文:
uw
截断为零长度或创建用于写入的文本文件,默认权限
ua
附加; 打开或创建文本文件,以便在文件结束时写入默认权限
uwb
截断为零长度或创建二进制文件以进行写入,默认权限
uab
附加; 打开或创建二进制文件,以便在文件结束时写入默认权限
uw+
截断为零长度或创建文本文件以进行更新,默认权限
ua+
附加; 打开或创建文本文件以进行更新,在文件结束时写入默认权限
uw+b
或uwb+
截断为零长度或创建二进制文件以进行更新,默认权限
ua+b
或uab+
附加; 打开或创建二进制文件以进行更新,在文件结束时写入默认权限
如果底层系统支持这些概念,则打开用于写入的文件应使用独占(也称为非共享)访问来打开.如果正在创建文件,并且模式字符串的第一个字符不是"u",则在底层系统支持的范围内,该文件应具有文件权限,以防止系统上的其他用户访问该文件.如果正在创建文件并且模式字符串的第一个字符是"u",则在文件关闭时,它应具有系统默认文件访问权限10).
如果文件被成功打开,然后将指针
FILE
指向的由streamptr
将被设置为指向对象控制打开的文件.否则,指针FILE
指向streamptr
将被设置为一个空指针.返回
fopen_s
如果打开文件,该函数返回零.如果它没有打开文件或者存在运行时约束违规,则fopen_s
返回非零值.10)这些权限与fopen创建的文件相同.
fopen_s()
Microsoft已将该函数添加到C运行时,其基本区别如下fopen()
:
如果打开文件进行写入(模式中指定的"w"或"a"),则打开文件以进行独占(非共享)访问(如果平台支持).
如果在带有"w"或"a"说明符的mode参数中使用"u"说明符,那么在文件关闭时,它将具有系统默认权限,供其他用户访问该文件(可能不是访问,如果这是系统默认值).
如果在这些情况下未使用指定的"u" ,则在文件关闭时(或之前)将设置文件的权限,以便其他用户无权访问该文件.
本质上,它意味着默认情况下应用程序写入的文件不受其他用户的保护.
他们没有这样做,fopen()
因为现有代码可能会破裂.
Microsoft已选择弃用fopen()
以鼓励Windows开发人员有意识地决定其应用程序使用的文件是否具有松散权限.
Jonathan Leffler的回答提供了建议的标准化语言fopen_s()
.我添加了这个答案,希望能够明确理由.