fopen / fopen_s并写入文件

时间:2010-04-04 16:48:49

标签: c file-io precision fopen

我在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位数。我对吗?

6 个答案:

答案 0 :(得分:18)

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

您可以使用说明符printf%.xg函数族指定精度数字,其中 x 是输出中所需精度的数字。 long double从平台到平台的精度各不相同,但您通常可以认为它至少是16位十进制精度。

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

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

答案 1 :(得分:10)

我遇到了与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 ++编译器上编译

答案 2 :(得分:6)

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

  2. 是的,long double很容易获得15位精度;实际上,即使是常规的双打也足够好(但不会更多)。

答案 3 :(得分:4)

其他海报指出,fopen并非真的非常不安全。如果你不想要这个警告,但你确实想要其他那些警告真正的漏洞,请不要 #define _CRT_SECURE_NO_WARNINGS

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

答案 4 :(得分:4)

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

答案 5 :(得分:1)

在包含任何文件之前定义_CRT_SECURE_NO_WARNINGS以摆脱此警告,并停止相信MS对fopen

的看法