fopen / fopen_s 并写入文件

发布于 2024-08-27 07:03:01 字数 736 浏览 5 评论 0原文

我在 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);  
}  

我的问题:

  1. 在使用 MVS2008 进行编译时,我收到警告:警告 C4996:'fopen':此函数或变量可能不安全。考虑使用 fopen_s 代替。我还没有看到太多关于 fopen_s 的信息,因此我可以更改我的代码。有什么建议吗?

  2. 可以指示fprintf以所需的数值精度将数字写入文件吗?如果我使用long double,那么我认为我的答案在小数点后 15 位之前都是好的。我说得对吗?

I'm using fopen in C to write the output to a text file. The function declaration is (where ARRAY_SIZE has been defined earlier):

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:

  1. 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_s so that I can change my code. Any suggestions?

  2. Can one instruct fprintf to write numbers at a desired numerical precision to a file? If I'm using long double then I assume that my answers are good till 15 digits after the decimal point. Am I right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

煮茶煮酒煮时光 2024-09-03 07:03:01

fopen_sfopen 的变体,它包含参数验证,并返回错误代码而不是指针,以防在打开过程中出现问题。它比基本变体更安全,因为它考虑了更多边缘条件。编译器警告您使用它,因为 fopen 代表应用程序中的潜在利用向量。

您可以使用说明符 %.xgprintf 系列函数指定精度数字,其中 x 是您想要的精度数字在输出中。 long double 的精度因平台而异,但通常可以保证其精度至少为 16 位小数。

编辑:虽然我并不完全同意其他人的观点,他们认为 fopen_s 完全是浪费时间,但它确实代表了相当低的利用机会,而且它没有得到广泛支持。然而,C4996 下警告的其他一些功能是更严重的漏洞,使用 _CRT_SECURE_NO_WARNINGS 相当于关闭“您未锁卧室门”和“您未锁卧室门”的警报。厨房里的核弹”。

只要您的项目不限于使用“纯 C”(例如,学校作业或嵌入式微控制器),您就可以很好地利用几乎所有现代 C 编译器也是 C++ 编译器并使用所有这些 I/O 函数的 C++ iostream 变体,以便同时提高安全性和兼容性。

fopen_s is a variant of fopen which 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 fopen represents a potential exploitation vector in your application.

You can specify digits of precision to the printf family of functions by using the specifier %.xg, where x is the digits of precision you want in the output. A long double varies in precision from platform to platform, but you can generally bet on it being at least 16 digits of decimal precision.

Edit: While I'm not entirely on board with the others who are suggesting that fopen_s is a complete waste 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_WARNINGS is the equivalent of turning off the alarm for both "you left your bedroom door unlocked" and "you left a nuclear bomb in the kitchen".

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++ iostream variants of all of these I/O functions in order to get both improved security and compatibility at the same time.

孤君无依 2024-09-03 07:03:01

我在使用 Visual Studio 2012 时遇到了类似的问题,但我的问题扩大了,我正在构建一个程序,我想使用 Visual Studio 的功能进行测试,并最终能够在我的计算机上编译和运行相同的应用程序。 Linux 服务器(我正在制作一个机器人),

所以这是我在 Google 一番之后想到的,并认为我会发布它,以防它可以帮助其他人。

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

这将安抚 Visual Studio,它不会抱怨,并且还允许在 gcc 或任何其他符合标准的 c/c++ 编译器上编译相同的代码

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)

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

知你几分 2024-09-03 07:03:01
  1. fopen_s 和所有其他 _s 函数都是 MS 特定的标准函数的“安全”变体。如果您的代码不需要跨平台,您可以直接切换并使编译器满意。否则,只需将 _CRT_SECURE_NO_WARNINGS 预处理器指令添加到您的项目设置中,它就会停止向您发出警告。

  2. 是的,long double 很容易达到 15 位精度;事实上,即使是普通的双打也足够好了(但仅此而已)。

  1. fopen_s and 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_WARNINGS pre-processor directive into your project settings and it'll stop warning you about it.

  2. Yeah, long double is easily good for 15 digits of precision; actually, even regular doubles are good enough for that much (but no more).

苏别ゝ 2024-09-03 07:03:01

从 fopen 移动到 fopen_s 禁用了在打开和写入文件时在记事本(只读)中打开文件的功能。
切换回 fopen,我可以在程序写入文件时读取文件。

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.

莫相离 2024-09-03 07:03:01

其他发帖者指出 fopen 并不是真的很不安全。如果您不想要此警告,但确实想要其他警告真正漏洞的警告,则不要
#define _CRT_SECURE_NO_WARNINGS

相反,下次收到 fopen 警告时,请单击“查看‘fopen’声明”行。这将带您到 stdio.h 中注入警告的行。从该行删除文本 _CRT_INSECURE_DEPRECATE(fopen_s) ,当您使用 fopen 时将不再收到安全警告,但对于 strcpy、strdup 和其他可能危险的警告,它将保留。

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.

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.

梅窗月明清似水 2024-09-03 07:03:01

只需在包含任何文件之前定义 _CRT_SECURE_NO_WARNINGS 即可消除此警告,并停止相信 MS 关于 fopen 的说法

Just define _CRT_SECURE_NO_WARNINGS before you include any file to get rid of this warnings, and stop believe to what MS says about fopen

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文