web-dev-qa-db-ja.com

Cの末尾のヌルスペースなしのsprintf()

出力の最後に「\ 0」文字を追加せずにC sprintf()関数を使用する方法はありますか?固定幅の文字列の途中でフォーマットされたテキストを書く必要があります。

40
zaratustra

sprintf()に末尾のヌルを書き込まないように指示する方法はありません。 sprintf()を使用して一時的な文字列に書き込み、strncpy()のようなものを使用して必要なバイトのみをコピーします。

42
Greg Hewgill

sprintfは、書き込まれた文字列の長さ(ヌル端末を含まない)を返します。これを使用して、ヌル端末がどこにあるかを知り、ヌル端末文字を別の文字(つまりスペース)に変更できます。 strncpyを使用するよりも効率的です。

 unsigned int len = sprintf(str, ...);
 str[len] = '<your char here>';
25
Doug T.

Sprintf()を使用してこれを行うことはできませんが、プラットフォームによっては、snprintf()を使用してmayできる場合があります。

置換する文字数を知る必要があります(ただし、文字列の途中に文字を入れているので、とにかくそれを知っているでしょう)。

これは、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で終了するようです。

4
Roddy

固定幅文字列を次のようなフォーマット文字列として使用することもできます。

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

1
Nathan Fellman

固定領域に書き込むので、次のようにできます。

// 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;
0
Todd Freed

実際、snprintfを使用する場合、この例ではnullは追加されません。

char name[9] = "QQ40dude";  
unsigned int i0To100 = 63;  
_snprintf(&name[2],2,"%d",i0To100);  
printf(name);// output will be: QQ63dude  
0
yan bellavance