1

vsnprintf()1 より大きい負の値を返すことができますか? もしそうなら、それはどのような状況下でそうしますか?

char配列のフォーマット指定子として使用しようとし%lsましたが、割り当てられた配列よりも大きくコピーしようとしました。どちらの場合も、戻り値として -1 を取得しています。

4

2 に答える 2

3

はい、できます。「許可されている」のように。状況はプラットフォームによって異なり、いかなる方法でも指定または規制されていません。戻り値に関係する唯一の移植可能なこと< 0は、エラーがあったかどうかを確認することです。

標準から(7.21.6.12(3)、vsnprintf):

nullで終了する出力は、戻り値が負でなく、未満の場合にのみ完全に書き込まれnます。

もちろん、どのプラットフォームでも、戻り値について追加の保証を行うことができます。ドキュメントを参照してください。

于 2012-02-01T07:00:14.710 に答える
3

C99 標準は次のように述べています。

§7.19.6.12vsnprintf関数

#include <stdarg.h>
#include <stdio.h>
int vsprintf(char *restrict s, size_t n, const char *restrict format, va_list arg);

説明

¶2 この関数は、可変引数リストが に置き換えられたvsnprintfと同等であり、マクロ (および場合によっては後続の呼び出し)によって初期化されている必要があります。関数はマクロを呼び出しません 。245)重複するオブジェクト間でコピーが行われる場合、動作は未定義です。snprintfargva_startva_argvsnprintfva_end

戻り値

¶3 この関数は、エンコーディング エラーが発生した場合は、終端のヌル文字をカウントせずに、十分に大きかった場合にvsnprintf書き込まれる文字数を返すか、負の値を返します。nしたがって、戻り値が非負で より小さい場合にのみ、null で終了する出力が完全に書き込まれますn

245)関数vfprintfvfscanfvprintfvscanfvsnprintfvsprintfおよび がマクロをvsscanf呼び出すため、戻り後の の値は不定です。va_argarg

で定義されているため、snprintf()そのセクションは次のとおりです。

§7.19.6.5snprintf関数

#include <stdio.h>
int snprintf(char *restrict s, size_t n, const char *restrict format, ...);

説明

¶2 このsnprintf関数は と同等ですが、出力がストリームではなくfprintf配列 (引数 で指定) に書き込まれる点が異なります。sゼロの場合nは何も書き込まれずs、null ポインターの可能性があります。それ以外の場合、-1 番目を超える出力文字nは配列に書き込まれるのではなく破棄され、実際に配列に書き込まれる文字の最後に null 文字が書き込まれます。重複するオブジェクト間でコピーが行われる場合、動作は未定義です。

戻り値

¶3 この関数は、エンコーディング エラーが発生した場合は、終端のヌル文字をカウントせずに、十分に大きかった場合にsnprintf書き込まれる文字数を返すか、負の値を返します。nしたがって、戻り値が非負で より小さい場合にのみ、null で終了する出力が完全に書き込まれますn


-1エラーで戻るとは言っていません。任意の負の値。そうです、エラーで 1 より大きい大きさの負の値を与えることは許可されています。


マイクロソフトのバージョン

vsnprintfVisual Studio 2015の Microsoft の仕様には次のように記載されていることに注意してください。

vsnprintf終了のヌル文字を数えずに、書き込まれた文字数を返します。-1 の戻り値は、エンコード エラーが発生したことを示します。count で指定されたバッファー サイズが、format と argptr で指定された出力を格納するには十分に大きくない場合、vsnprintf の戻り値は、count が十分に大きい場合に書き込まれる文字数になります。戻り値が count - 1 より大きい場合、出力は切り捨てられています。

書き込む文字数が count 以下の場合は、と の両方が書き込まれた文字数_vsnprintfを返します。_vsnwprintf書き込む文字数が count より大きい場合、これらの関数は -1 を返し、出力が切り捨てられたことを示します。すべての関数の戻り値には、終端の null が記述されている場合は含まれません。

これは必ずしもそうではないことに注意してください。

Visual Studio 2015 および Windows 10 の UCRT 以降、vsnprintfは と同一ではなくなりました_vsnprintf。このvsnprintf関数は C99 標準に準拠しています。_vnsprintf下位互換性のために保持されています。

比較のために、Visual Studio 2013 のドキュメントには次のように記載されています。

vsnprintf_vsnprintf、および_vsnwprintf書き込む文字数が count 以下の場合は書き込まれた文字数を返します。書き込む文字数が count より大きい場合、これらの関数は -1 を返し、出力が切り捨てられたことを示します。戻り値には、終端の null が書き込まれている場合は含まれません。

比較可能なページは次のsnprintf()とおりです。

于 2012-02-01T07:36:32.020 に答える