有没有办法使用fopen_s()与海湾合作委员会或至少创建一个关于它的#define的方法吗?(Is

2019-08-17 05:19发布

MSVC编译器说, fopen()已被弃用,建议使用fopen_s()

有没有办法使用fopen_s()仍然是便携式?

任何想法了#define

Answer 1:

微软*_s功能是不可移植的,我通常使用相当于C89 / C99的功能,并禁用废弃警告( #define _CRT_SECURE_NO_DEPRECATE )。

如果你坚持,你可以使用适配器功能(不一定是宏!),其代表fopen()就没有平台fopen_s()但你必须要小心的值映射errno_t返回代码errno

errno_t fopen_s(FILE **f, const char *name, const char *mode) {
    errno_t ret = 0;
    assert(f);
    *f = fopen(name, mode);
    /* Can't be sure about 1-to-1 mapping of errno and MS' errno_t */
    if (!*f)
        ret = errno;
    return ret;
}

不过,我看不出fopen_s()是比任何更安全fopen() ,所以我通常去的便携性。



Answer 2:

如果您使用的是C11, fopen_s是一个标准库:

http://en.cppreference.com/w/c/io/fopen

gcc需要使用--std=C11参数。



Answer 3:

在C / C ++代码,

#ifdef __unix
#define fopen_s(pFile,filename,mode) ((*(pFile))=fopen((filename),(mode)))==NULL
#endif

在Makefile文件

CFLAGS += -D'fopen_s(pFile,filename,mode)=((*(pFile))=fopen((filename),(mode)))==NULL'

注意,成功fopen_s返回0,而返回的fopen一个非零的文件指针。 因此,有必要加上“== NULL”到宏观,如结束:

if (fopen_s(&pFile,filename,"r")) perror("cannot open file");


Answer 4:

许多微软的安全功能都包含在C11标准的附录K,但没有得到广泛的支持,因此便携性仍然是一个问题。 有必要在某些应用中,提高了安全性; 也许支持将在今后改进。

我过去,我这样做是这样的:

  #define fopen_s(fp, fmt, mode)          *(fp)=fopen( (fmt), (mode))

宏是简单和直接的,够用的东西快速和肮脏的,但它不提供fopen_s外行为,它不会提供真正的fopen_s功能的安全性。

@Alex B的上述部分功能的方法再现失败的正确行为; 他将返回错误号(= EINVAL)。 他的做法可能会进一步通过生成一个无效的参数异常更充分地再现fopen_s的行为进行扩展。



Answer 5:

Accroding到https://en.cppreference.com/w/c/io/fopen有可能使* _s上STDC库函数

“与所有边界检查功能,fopen_s仅保证可供如果STDC_LIB_EXT1由实现所定义,并且如果用户包括stdio.h中之前定义STDC_WANT_LIB_EXT1为整数常数1”。



文章来源: Is there a way to use fopen_s() with GCC or at least create a #define about it?