C99 ドラフト標準では、そのような場合に何が起こるべきかを明示的に述べていませんが、複数のバリエーションを検討することで、すべての場合に仕様を満たすように特定の方法で動作する必要があることを示すことができます。
標準は次のように述べています。
%s - 一連の非空白文字に一致します.252)
l 長さ修飾子が存在しない場合、対応する引数は、シーケンスを受け入れるのに十分な大きさの文字配列の最初の要素へのポインターと、自動的に追加される終端の null 文字になります。
標準を満たすために提案している方法で機能する必要があることを示す例を次に示します。
例 A:
char buffer[4] = "abcd";
char buffer2[10]; // Note the this could be placed at what would be buffer+4
sscanf("123 4", "%s %s", buffer, buffer2);
// Result is buffer = "123\0"
// buffer2 = "4\0"
例 B:
char buffer[17] = "abcdefghijklmnop";
char* buffer2 = &buffer[4];
sscanf("123 4", "%s %s", buffer, buffer2);
// Result is buffer = "123\04\0"
sscanf のインターフェースは、これらが異なっていることを実際に知るのに十分な情報を提供しないことに注意してください。したがって、例 B が適切に機能するためには、例 A のヌル文字の後のバイトをいじってはなりません。これは、このビットの仕様に従って両方のケースで機能する必要があるためです。
したがって、暗黙のうちに、仕様のためにあなたが述べたように機能する必要があります。
他の関数にも同様の引数を配置できますが、この例からアイデアを確認できると思います。
注: 「%16s」などの形式でサイズ制限を指定すると、動作が変わる可能性があります。仕様では、データをバッファーに書き込む前に、sscanf がバッファーをその制限までゼロにすることは機能的に許容されます。実際には、ほとんどの実装はパフォーマンスを選択します。つまり、残りはそのままにしておきます。
仕様の意図がこの種のゼロ化を行うことである場合、通常は明示的に指定されます。strncpy は一例です。文字列の長さが指定された最大バッファー長より短い場合、残りのスペースは null 文字で埋められます。この同じ「文字列」関数が終了していない文字列を返す可能性があるという事実により、これは人々が独自のバージョンを展開する最も一般的な関数の 1 つになります。
fgets に関する限り、同様の状況が発生する可能性があります。唯一の落とし穴は、何も読み込まれない場合、バッファはそのままであると仕様が明示的に述べていることです。許容可能な機能実装では、バッファーをゼロにする前に読み取るバイトが少なくとも 1 バイトあるかどうかを確認することで、これを回避できます。