web-dev-qa-db-ja.com

sprintf_sはこのスコープで宣言されていません

sprintf_sを使用するCプログラムがあります。 Windowsでは問題なく動作しますが、Linuxでコードをコンパイルすると、次のエラーが発生します。

sprintf_s was not declared in this scope.

なぜこれが発生し、どうすれば修正できますか?

21
SPB

これは標準ではありません。Linuxではそのような機能は見つかりません。

標準関数snprintfも同様のセマンティクスを持つ必要があります。

31
peoro

sprintf_sは標準Cライブラリの一部ではないため、移植性がないため、Linuxでは使用できません。しかし、あなたはsnprintfを持っています。これは非常に似ており、あなたが望むものを達成するのを助けるはずです。

7
gnclmorais

sprintf_sは標準Cライブラリの一部ではないため、Linuxでは使用できません。

ただし、snprintfは標準であり、同じタスクを実行する必要があります。

sprintf_sはAnnex Kの一部であり、C = 11標準のオプションのAnnexです。

附属書K

...

K.2スコープ

  1. この附属書は、プログラムのセキュリティ脆弱性の軽減に役立つ一連のoptional拡張を指定します、および既存の標準ヘッダーで宣言または定義された新しい関数、マクロ、およびタイプで構成されます。

...

K.3.5.3.6 sprintf_s関数

あらすじ

#define __STDC_WANT_LIB_EXT1__1
#include <stdio.h>
int sprintf_s(char * restrict s, rsize_t n,
const char * restrict format, ...);

(強調を追加)

それは決してPOSIX(またはLinux)に組み込まれませんでした(そして決して見逃されていません。委員会でのその有用性についてさえ議論があります)。

移植性を高めるには、コア標準の一部であり、必要なすべての機能を提供する snprintf を使用します。

5
Deduplicator

snprintfは安全ではなく、sprintf_sのみが安全です。 snprintfは、最後の\ 0を追加することを保証しないため、後続のオーバーフローが発生する可能性があります。適切な実装については、 https://github.com/rurban/safeclib を参照してください。

1
rurban

私のプログラムをWindowsからLinuxに移植しているときに、自分のwindows.hに次の実装を記述しました。

inline int sprintf_s(char* buffer, size_t sizeOfBuffer, const char* format, ...)
{
    va_list ap;
    va_start(ap, format);
    int result = vsnprintf(buffer, sizeOfBuffer, format, ap);
    va_end(ap);
    return result;
}

template<size_t sizeOfBuffer>
inline int sprintf_s(char (&buffer)[sizeOfBuffer], const char* format, ...)
{
    va_list ap;
    va_start(ap, format);
    int result = vsnprintf(buffer, sizeOfBuffer, format, ap);
    va_end(ap);
    return result;
}
0
Andrey