Sprintf() без конечного нулевого пространства в C

Есть ли способ использовать функцию c sprintf() без добавления символа '\ 0' в конце вывода? Мне нужно написать форматированный текст в середине строки с фиксированной шириной.

Ответ 1

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

Ответ 2

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

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

Ответ 3

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

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

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

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

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

После этого "123" заменяется на "Joe".

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

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

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

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

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

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