none
sprintfがエラーになる条件など RRS feed

  • 質問

  • http://msdn.microsoft.com/ja-jp/library/ce3zzk1k(VS.100).aspx

    等を探してみたのですが、

    1) sprintf()がエラーとなるのはどんな条件なのか?(どのような場合にエラーとなるのか)

     2) エラーとなった場合、パラメーターbufferの内容はどうなっているのか?(中途半端に書き変わっている?or先頭にNUL文字が格納されている?or呼び出された状態のまま?、等)

    について分かりませんでした。 どこかに情報がないでしょうか?

    ご教示願います。

    2010年5月28日 2:41

回答

  • buffer または format が null ポインターである場合、sprintf_s および swprintf_s は -1 を返し、errno を EINVAL に設定します。

    と、書いてあるとおりではないでしょうか。

    条件が書いてあるので、実行して確かめることが出来るのではないでしょうか。


    Jitta@わんくま同盟
    2010年6月3日 1:32

すべての返信

  • 回答ではありません。あしからず。
    sprintf()は受け取り側のバッファの長さを知りませんので、バッファオーバーラン
    により、容易にアプリケーションを破壊します。また、フォーマット文字列に依存して
    スタックを走査するので、引数の型や個数や順番に矛盾があってはなりません。従って、
    この関数は「問題なく処理結果が得られることが確実である」状態でしか使えないと想像できます。
    この考えによると、エラーとなった状態を気にする必要はないと考えられます。

    • 回答の候補に設定 山本春海 2010年6月8日 6:43
    2010年5月28日 5:14
  • buffer または format が null ポインターである場合、sprintf_s および swprintf_s は -1 を返し、errno を EINVAL に設定します。

    と、書いてあるとおりではないでしょうか。

    条件が書いてあるので、実行して確かめることが出来るのではないでしょうか。


    Jitta@わんくま同盟
    2010年6月3日 1:32
  • Jittaさんが既に書かれている通り、エラーになる条件は書かれているのでそれで解決ですね。

    基本的にエラーが発生した時の返却内容を説明していない場合、エラーが起こった時の返却内容に関しては
    保証しないと言うのが普通だと思います。つまりエラー時の返却内容は不定と言うことです。

    ですから、特定の状態である事を期待したコードを書く事は危険ですし、するべきでは無いと思います。
    こういう場合、エラーが起こった時は返却値を受けた変数の内容を利用しないようにするべきだと思います。

    もしくは、エラー時は変数を初期化してしまい必ず初期値の状態になるようにプログラマの責任で管理するかでしょう。

     


    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    • 回答の候補に設定 山本春海 2010年6月8日 6:43
    2010年6月4日 0:56
  • (しばらく見ていませんでしたので返信が遅れました)

    確かにリファレンスには「buffer または format が null ポインターである場合」はエラーになることが書いてあるので、それは分かります。

    が、他にもエラーとなる条件がありそうな記述だったので、質問した次第です。つまり「buffer または format が null ポインターである場合」"だけ"がエラーとなる、とは明記されていないです。

    ちなみに、もし「buffer または format が null ポインターである場合」"だけ"なのであれば、実験していませんが、「パラメーターbufferの内容」についてはあまり重要ではないです。※その場合はsprintf()を実行しないので...

    2010年6月15日 3:13
  • > この関数は「問題なく処理結果が得られることが確実である」状態でしか使えない

    はい。これから作るソースについてはその認識です。

    ※質問は、記述していませんでしたが、既に動作しているソースに関する話題でした。

    2010年6月15日 3:17
  • > 特定の状態である事を期待したコードを書く事は危険

    はい。その認識はあります...

    2010年6月15日 3:18
  • が、他にもエラーとなる条件がありそうな記述だったので、質問した次第です。

     例えば、次のようなコードが実行された場合、おかしな状態になることが予想されます。

    
    short a = 255;
    long int b = 255;
    char buff[100];
    sprintf_s(buff, sizeof(buff), "%ld, %d", a, b);
    

     つまり、a は short なので、%ld に相当するだけの幅を持っていません。反対に b は long なので、%d ではサイズが足りません。おそらく、sprintf_s では、エラーになったように思います。

    sprintf_s と sprintf 間の主な違いとしては、sprintf_s は書式指定文字列の有効な書式指定文字をチェックしますが、sprintf は書式指定文字列またはバッファーが NULL ポインターかどうかのみをチェックします。


    Jitta@わんくま同盟
    2010年7月27日 13:07