Как использовать strlen() для форматированной строки?
Я хотел бы написать функцию-обертку для функций ncurses mvwprint / mvwchgat, которая печатает сообщение в указанном окне и затем изменяет его атрибуты.
Однако mvwchgat нужно знать, сколько символов он должен изменить - и я не знаю, как сказать mvwchgat, какова длина отформатированной строки, поскольку, например, при использовании strlen() "abc%d"
очевидно, возвращает 5, потому что Стрлен не знает, что %d
обозначает...
2 ответа
В C99 или C11 вы можете использовать такую строку:
length = snprintf(NULL, 0, format_string, args);
Из руководстваsnprintf
(выделение мое):
Функции snprintf() и vsnprintf() записывают не больше байтов размера (включая завершающий нулевой байт ('\0')). Если выходные данные были усечены из-за этого ограничения, тогда возвращаемое значение - это количество символов (исключая завершающий нулевой байт), которое было бы записано в последнюю строку, если бы было достаточно места. Таким образом, возвращаемое значение размера или более означает, что вывод был усечен.
Так как мы даем snprintf
0 в качестве размера, то вывод всегда обрезается, а вывод snprintf
было бы количество символов, которые были бы написаны, который в основном является длиной строки.
В C89 у вас нет snprintf
, Обходной путь - создать временный файл или, если вы открыли *nix /dev/null
и напишите что-то вроде этого:
FILE *throw_away = fopen("/dev/null", "w"); /* On windows should be "NUL" but I haven't tested */
if (throw_away)
{
fprintf(throw_away, "<format goes here>%n", <args go here>, &length);
fclose(throw_away);
} /* else, try opening a temporary file */
Вы не можете знать заранее, как долго будет длиться ваша строка:
printf("abc%d", 0); //4 chars
printf("abc%d", 111111111);//12 chars
Все с одинаковой строкой формата.
Единственный верный способ заключается в sprintf
рассматриваемый текст в буфер, strlen(buffer)
результат и printf("%s", buffer);
результат на экран.
Это решение позволяет избежать двойного форматирования за счет выделения достаточно длинного буфера.