2008-12-10 1 views

ответ

36

Невозможно сообщить sprintf(), чтобы не писать конечный нуль. То, что вы можете сделать, это использовать sprintf() для записи во временную строку, а затем что-то вроде strncpy(), чтобы скопировать только те байты, которые вы хотите.

+2

bleh, я боялся этого. Благодарю. – zaratustra 2008-12-10 18:38:01

+1

Или используйте memmove() или возможно memcpy(), а не strncpy(). – 2008-12-10 18:59:40

+1

snprintf, любой ...? – Roddy 2008-12-11 16:50:00

22

sprintf возвращает длину строки, записанной (не считая нулевого терминала), вы можете использовать это, чтобы знать, где находится нулевой терминал, и изменить символ нулевого терминала на что-то другое (т. Е. Пробел). Это будет более эффективно, чем использование strncpy.

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

Вы также можете использовать фиксированную строку по ширине как формат строки, как это:

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

3

Вы не можете сделать это с помощью sprintf(), но вы: may сможет использовать snprintf(), в зависимости от вашей платформы.

Вам нужно знать, сколько символов вы заменяете (но по мере того, как вы помещаете их в середину строки, вы, вероятно, знаете, что так или иначе).

Это работает, потому что некоторые реализации snprintf() НЕ гарантируют записи завершающего символа - предположительно для совместимости с такими функциями, как stncpy().

char message[32] = "Hello 123, it's good to see you."; 

snprintf(&message[6],3,"Joe"); 

После этого «123» заменяется на «Джо».

О реализации, где snprintf() гарантирует завершение нумерации, даже если строка усечена, это не сработает. Поэтому, если переносимость кода вызывает беспокойство, вам следует избегать этого.

Большинство Windows-based versions snprintf() демонстрируют это поведение.

Но, MacOS и BSD (и, возможно, linux), всегда имеют нуль-конец.

0

Поскольку вы пишете к (, 3, "ABCDEF" "% * s.") фиксированная область, то вы можете сделать это следующим образом:

// 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

На самом деле этот пример не добавит нулевое значение, если вы используете snprintf:

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