23

我在 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 编译时,我收到警告:warning C4996: 'fopen': This function or variable may be unsafe。考虑改用 fopen_s。我没有看到太多关于fopen_s我可以更改代码的信息。有什么建议么?

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

4

6 回答 6

21

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

您可以使用说明符为printf函数族指定精度位数%.xg,其中x是您希望在输出中使用的精度位数。Along double的精度因平台而异,但您通常可以打赌它至少为 16 位小数精度。

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

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

于 2010-04-04T17:09:32.300 回答
11

我在使用 Visual Studio 2012 时遇到了类似的问题,但我的问题扩展的地方是我正在构建一个程序,我想使用 Visual Studio 的花里胡哨进行测试,并最终能够在我的Linux 服务器(我正在制作一个机器人)

所以这是我在谷歌搜索后想出的,并认为我会发布它以防它对其他人有帮助。

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++ 编译器上编译相同的代码

于 2013-02-19T20:21:09.090 回答
8
  1. fopen_s并且所有其他 _s 函数都是标准函数的特定于 MS 的“安全”变体。如果您的代码不需要跨平台,您可以切换并使编译器满意。否则,只需将_CRT_SECURE_NO_WARNINGS预处理器指令添加到您的项目设置中,它就会停止警告您。

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

于 2010-04-04T17:06:30.447 回答
5

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

于 2013-10-27T13:15:52.690 回答
4

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

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

于 2011-04-15T14:24:40.500 回答
0

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

于 2010-04-04T17:03:08.457 回答