C语言 fopen / fopen_s 并写入文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2575116/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
fopen / fopen_s and writing to files
提问by yCalleecharan
I'm using fopen in C to write the output to a text file. The function declaration is (where ARRAY_SIZEhas been defined earlier):
我在 C 中使用 fopen 将输出写入文本文件。函数声明是(ARRAY_SIZE之前定义的地方):
void create_out_file(char file_name[],long double *z1){
FILE *out;
int i;
if((out = fopen(file_name, "w+")) == NULL){
fprintf(stderr, "***> Open error on output file %s", file_name);
exit(-1);
}
for(i = 0; i < ARRAY_SIZE; i++)
fprintf(out, "%.16Le\n", z1[i]);
fclose(out);
}
My questions:
我的问题:
On compilation with MVS2008 I get the warning: warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. I haven't see much information on
fopen_sso that I can change my code. Any suggestions?Can one instruct
fprintfto write numbers at a desired numerical precision to a file? If I'm usinglong doublethen I assume that my answers are good till 15 digits after the decimal point. Am I right?
在使用 MVS2008 编译时,我收到警告:警告 C4996:'fopen':此函数或变量可能不安全。考虑使用 fopen_s 代替。我没有看到太多关于
fopen_s我可以更改代码的信息。有什么建议?可以指示
fprintf以所需的数值精度将数字写入文件吗?如果我正在使用,long double那么我认为我的答案在小数点后 15 位之前都很好。我对吗?
采纳答案by Dan Story
fopen_sis a variant of fopenwhich contains parameter validation and hands back an error code instead of a pointer in case something goes wrong during the open process. It's more secure than the base variant because it accounts for more edge conditions. The compiler is warning you to use it because fopenrepresents a potential exploitation vector in your application.
fopen_s是它的一个变体,fopen它包含参数验证并返回一个错误代码而不是一个指针,以防在打开过程中出现问题。它比基本变体更安全,因为它考虑了更多的边缘条件。编译器警告您使用它,因为它fopen代表您的应用程序中的潜在利用向量。
You can specify digits of precision to the printffamily of functions by using the specifier %.xg, where xis the digits of precision you want in the output. A long doublevaries in precision from platform to platform, but you can generally bet on it being at least 16 digits of decimal precision.
您可以使用说明符为printf函数族指定精度位数%.xg,其中x是您希望在输出中使用的精度位数。Along double的精度因平台而异,但您通常可以打赌它至少是 16 位十进制精度。
Edit: While I'm not entirely on board with the others who are suggesting that fopen_sis a completewaste of time, it does represent a pretty low chance of exploitation and it isn't widely supported. Some of the other functions warned about under C4996 are much more serious vulnerabilities, however, and using _CRT_SECURE_NO_WARNINGSis the equivalent of turning off the alarm for both "you left your bedroom door unlocked" and "you left a nuclear bomb in the kitchen".
编辑:虽然我并不完全同意其他人的意见,他们认为fopen_s这完全是在浪费时间,但它确实代表了极低的利用机会,并且没有得到广泛支持。然而,在 C4996 下警告的一些其他功能是更严重的漏洞,使用_CRT_SECURE_NO_WARNINGS相当于关闭“你没有打开卧室门”和“你在厨房里留下核弹”的警报。
As long as you aren't restricted to using "pure C" for your project (e.g. for a school assignment or an embedded microcontroller), you would do well to exploit the fact that almost all modern C compilers are also C++ compilers and use the C++ iostreamvariants of all of these I/O functions in order to get both improved security andcompatibility at the same time.
只要您不限于在您的项目中使用“纯 C”(例如,用于学校作业或嵌入式微控制器),您最好利用几乎所有现代 C 编译器也是 C++ 编译器的事实,并使用iostream所有这些 I/O 函数的C++变体,以便同时获得更高的安全性和兼容性。
回答by BrierMay
I ran into a similar problem working with Visual Studio 2012 but where my problem expanded was I'm building a program that I want to use the bells and whistles of Visual Studio for testing and eventually be able to compile and run the same application on my Linux server (I'm making a bot)
我在使用 Visual Studio 2012 时遇到了类似的问题,但我的问题扩展到我正在构建一个程序,我想使用 Visual Studio 的花里胡哨进行测试,并最终能够在我的计算机上编译和运行相同的应用程序Linux 服务器(我正在制作一个机器人)
so this is what I came up with after some Google-ing and thought I'd post it in case it may help anyone else.
所以这就是我在谷歌搜索后想到的,并认为我会发布它以防它可以帮助其他人。
FILE *fp_config;
const char *configfile ;
configfile = "bot.conf";
#ifdef WIN32
errno_t err;
if( (err = fopen_s( &fp_config, configfile, "r" )) !=0 ) {
#else
if ((fp_config = fopen(configfile, "r")) == NULL) {
#endif
fprintf(stderr, "Cannot open config file %s!\n", configfile);
}
this will appease Visual Studio and it will not complain and it will also allow the same code to compile on gcc or any other standards compliant c/c++ compiler
这将安抚 Visual Studio,它不会抱怨,它还允许在 gcc 或任何其他符合标准的 c/c++ 编译器上编译相同的代码
回答by tzaman
fopen_sand all the other _s functions are MS-specific "secure" variants of standard functions. If your code doesn't need to be cross-platform, you can just switch and make the compiler happy. Otherwise, just add the_CRT_SECURE_NO_WARNINGSpre-processor directive into your project settings and it'll stop warning you about it.Yeah, long double is easily good for 15 digits of precision; actually, even regular doubles are good enough for that much (but no more).
fopen_s所有其他 _s 函数都是标准函数的特定于 MS 的“安全”变体。如果您的代码不需要跨平台,您可以切换并让编译器满意。否则,只需将_CRT_SECURE_NO_WARNINGS预处理器指令添加到您的项目设置中,它就会停止警告您。是的,long double 很容易达到 15 位精度;实际上,即使是普通的双打也足够了(但不能更多)。
回答by eduard
Moving from fopen to fopen_s disabled the ability to open file in notepad (read only) while file is opened and being writen. Swithing back to fopen and I can read wile my program writes the file.
从 fopen 移动到 fopen_s 禁用了在打开和写入文件时在记事本(只读)中打开文件的能力。切换回 fopen,我可以读取我的程序写入文件。
回答by AShelly
Other posters have pointed out that fopen is not really very unsafe. If you don't want this warning, but you do want the other ones that warn of real vulnerabilities, don't
#define _CRT_SECURE_NO_WARNINGS.
其他发帖者指出 fopen 并不是真的很不安全。如果您不想要此警告,但确实想要其他警告真正漏洞的警告,请不要
#define _CRT_SECURE_NO_WARNINGS。
Instead, the next time you get the fopen warning, click on the line that says "see declaration of 'fopen'". This will take you to the line in stdio.h which is injecting the warning. Delete the text _CRT_INSECURE_DEPRECATE(fopen_s)from that line, and you will no longer get the security warning when you use fopen, but it will remain for strcpy, strdup and those other possibly dangerous ones.
相反,下次您收到 fopen 警告时,请单击“查看 'fopen' 的声明”这一行。这将带您到 stdio.h 中注入警告的行。删除该_CRT_INSECURE_DEPRECATE(fopen_s)行中的文本,当您使用 fopen 时,您将不再收到安全警告,但对于 strcpy、strdup 和其他可能存在危险的内容,它将保留。
回答by Artyom
Just define _CRT_SECURE_NO_WARNINGSbefore you include any file to get rid of this warnings, and stop believe to what MS says about fopen
只需_CRT_SECURE_NO_WARNINGS在包含任何文件之前定义以消除此警告,并停止相信 MS 所说的内容fopen

