診断
コードには (少なくとも) 2 つの問題があります。
文字列を保存するための有用なスペースを提供していません。(定義された元の質問: char a[] = "";
、これは、長さ 1 の配列ですが、長さ 0 の文字列しか保持できません。)
scanf_s()
文字列の大きさを教えてくれませんでした。文字列へのポインタの後に長さ引数が必要です。
Microsoft の定義では、次のようにscanf_s()
指定されています。
およびとは異なりscanf
、wscanf
、、、、または で囲まれた文字列コントロール セットのすべての入力パラメータに対してバッファ サイズを指定する必要があります。文字単位のバッファー サイズは、バッファーまたは変数へのポインターの直後に追加のパラメーターとして渡されます。たとえば、文字列を読み取る場合、その文字列のバッファ サイズは次のように渡されます。scanf_s
wscanf_s
c
C
s
S
[]
char s[10];
scanf_s("%9s", s, _countof(s)); // buffer size is 10, width specification is 9
バッファー サイズには、終端の null が含まれます。幅指定フィールドを使用して、読み取られたトークンがバッファーに収まるようにすることができます。幅指定フィールドが使用されておらず、読み取られたトークンが大きすぎてバッファーに収まらない場合、そのバッファーには何も書き込まれません。
ノート
size パラメータの型unsigned
は ではなくsize_t
です。
_countof()
演算子は Microsoft 拡張機能です。これは とほぼ同等で、この場合は定義上sincesizeof(s) / sizeof(s[0])
と同じです。sizeof(s)
sizeof(char) == 1
size パラメータはであり、期待どおりunsigned
ではないことに注意してください。これは、 TR 24731-1機能の Microsoft 実装と ISO/IEC 9899:2011 の付属書 K とsize_t
の相違点の 1 つです。標準で指定されているサイズは技術的には ですが、制限された範囲で定義されています (したがって):rsize_t
size_t
r
タイプはrsize_t
typesize_t
です。
しかし、脚注 (表示されていません) は の定義を参照していますRSIZE_MAX
。
TR 24731 '安全な' 関数を使用していますか?も参照してください。
質問のコードを修正する
Microsoft からの引用の例は、主にコードを修正する方法を示しています。必要なもの:
int main(void)
{
char a[4096];
printf("Enter word:\n");
if (scanf_s("%s", a, (unsigned)sizeof(a)) != 1) // Note cast!
fprintf(stderr, "scanf_s() failed\n");
else
printf("scanf_s() read: <<%s>>\n", a);
return 0;
}
scanf_s()
動作すると仮定するのではなく結果をチェックし、標準エラーにエラーを報告したことに注意してください。