20

MSVC コンパイラは、これfopen()は非推奨であると述べており、 fopen_s().

fopen_s()ポータブルで使用する方法はありますか?

のアイデアはあり#defineますか?

4

6 に答える 6

32

Microsoft の*_s関数は移植性がありません。私は通常、同等の C89/C99 関数を使用し、非推奨の警告を無効にします ( #define _CRT_SECURE_NO_DEPRECATE)。

fopen()主張する場合は、を持たないプラットフォームでデリゲートするアダプタ関数 (必ずしもマクロである必要はありません!) を使用できますが、からの戻りコードfopen_s()の値をマッピングするように注意する必要があります。errno_terrno

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()。そのため、通常は移植性を重視します。

于 2009-10-03T08:44:32.840 に答える
8

C/C++ コードでは、

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

メイクファイル内

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");
于 2013-03-06T23:10:26.307 に答える
8

C11 を使用している場合fopen_sは、標準ライブラリです。

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

パラメータをgcc使用する必要があり--std=C11ます。

于 2015-03-08T18:10:05.770 に答える
3

Microsoft のセキュア機能の多くは C11 標準の Annex K に含まれていますが、広くサポートされていないため、移植性は依然として問題です。一部のアプリケーションでは、セキュリティを強化する必要があります。今後、サポートが改善される可能性があります。

私は過去に、次のようにしました:

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

このマクロはシンプルで単純明快で、手早く汚いものには十分ですが、fopen_s の例外動作を提供せず、実際の fopen_s 関数のセキュリティを提供しません。

上記の @Alex B の関数アプローチは、失敗時の適切な動作を部分的に再現します。彼は errno (= EINVAL) を返します。fopen_s の動作をより完全に再現するために無効なパラメータの例外を生成することで、彼のアプローチをさらに拡張することができます。

于 2016-02-04T06:24:24.510 に答える
-1
#define fopen_s(fp, fmt, mode)  ({\
    *(fp)=fopen( (fmt), (mode));\
    (*(fp) ) ? 0:errno;\
})
于 2019-07-23T14:36:21.850 に答える