出力の最後に '\0' 文字を追加せずに C の sprintf() 関数を使用する方法はありますか? 固定幅の文字列の途中にフォーマットされたテキストを書き込む必要があります。
8 に答える
sprintf()
末尾の null を書き込まないように指示する方法はありません。できることはsprintf()
、一時的な文字列に書き込むために使用してから、必要なstrncpy()
バイトだけをコピーするようなものです。
sprintf は、書き込まれた文字列の長さ (ヌル ターミナルを含まない) を返します。それを使用して、ヌル ターミナルがどこにあるかを知り、ヌル ターミナル文字を別のもの (つまり、スペース) に変更できます。これは、strncpy を使用するよりも効率的です。
unsigned int len = sprintf(str, ...);
str[len] = '<your char here>';
sprintf()を使用してこれを行うことはできませんが、プラットフォームによっては、snprintf()を使用して行うことができる場合があります。
置き換える文字の数を知る必要があります(ただし、文字列の途中に文字を入れるので、とにかくそれを知っているでしょう)。
これが機能するのは、snprintf()の一部の実装では、終了文字が書き込まれることを保証しないためです。おそらく、stncpy()などの関数との互換性のためです。
char message[32] = "Hello 123, it's good to see you.";
snprintf(&message[6],3,"Joe");
この後、「123」は「Joe」に置き換えられます。
文字列が切り捨てられてもsnprintf()がnull終了を保証する実装では、これは機能しません。したがって、コードの移植性が懸念される場合は、これを回避する必要があります。
ほとんどのWindowsベースのバージョンのsnprintf()は、この動作を示します。
しかし、MacOSとBSD(そしておそらくLinux)は常にnullで終了するように見えます。
次のように、固定幅の文字列をフォーマット文字列として使用することもできます。
char my_fixed_width_string_format[] = "need 10 chars starting here: %10s";
char my_fixed_width_string[40];
char string_to_print[] = "abcdefghijklmnop";
sprintf(my_fixed_width_string, my_fixed_width_string_format, string_to_print;
printf(my_fixed_width_string);
譲るべき
ここから始まる 10 文字が必要です: abcdefghij
固定領域に書き込んでいるので、次のようにできます。
// pointer to fixed area we want to write to
char* s;
// number of bytes needed, not including the null
int r = snprintf(0, 0, <your va_args here>);
// char following the last char we will write - null goes here
char c = s[r + 1];
// do the formatted write
snprintf(s, r + 1, <your_va_args here>);
// replace what was overwritten
s[r + 1] = c;
実際、snprintf を使用する場合、この例では null が追加されません。
char name[9] = "QQ40dude";
unsigned int i0To100 = 63;
_snprintf(&name[2],2,"%d",i0To100);
printf(name);// output will be: QQ63dude
ここを見てください:http://en.wikipedia.org/wiki/Printf
printf("%.*s", 3, "abcdef") は "abc" を出力します