Учитывая оператор printf в C, как мне создать буфер char * и узнать его длину?
У меня есть процесс MPI, который мне нужно распечатать в файл. Система MPI использует функциональные команды, такие как MPI_File_iwrite, которые принимают буфер (например, указатель на символ) и целую длину. Затем буфер печатается в файл.
Итак, чтобы напечатать то, что мне нужно напечатать в файл, мне нужно как-то заменить функцию printf на функцию, которая отображает преобразование форматирования в буфер char *. Это проблематично, поскольку строки могут различаться по длине... например:
printf("something %d, %d, %d, %f, etc.",x,y,z,p,d,...);
Как мне восстановить строку, которую производит printf-форматирование, выяснить, какая длина, и передать ее как char * в функцию mpi?
3 ответа
Похоже, вы хотите использовать snprintf
в достаточно большой буфер.
Если буфер был достаточно большим, возвращаемое значение snprintf
равно числу напечатанных символов. Вы можете вычислить длину выходной строки как минимум размера буфера и возвращаемого значения snprintf
,
Вы можете "напечатать" 0 байтов NULL
указатель с snprintf()
, В этом случае строка не будет написана, но snprintf()
будет по-прежнему вести себя нормально по отношению к его возвращаемому значению. Тогда вы можете выделить достаточно большой буфер.
Например:
size_t len;
len = snprintf(NULL, 0, "something %d, %d, %d, %f, etc.",x,y,z,p,d,...);
if (len > 0) {
char *buf = malloc(len + 1);
snprintf(buf, len + 1, "something %d, %d, %d, %f, etc.",x,y,z,p,d,...);
}
Это действительно только в C99 и далее.
Заметить, что snprintf()
может вернуть отрицательное значение, если есть ошибка преобразования. Это только несколько случаев, когда это может произойти, но, тем не менее, они существуют. В зависимости от спецификатора его вывод также может быть нулевым.
Исходя из вашего вопроса, я думаю, что ответ заключается в использовании sprintf()
или же snprintf()
скорее, чем printf()
- sprintf()
выводит в буфер и возвращает количество записанных символов без проверки того, что переданный буфер достаточно велик. snprintf()
принимает дополнительный аргумент, определяющий максимальное количество байтов для записи (что является более безопасным подходом).
char my_buf[MAX_LENGTH];
int bytes_written;
// using snprintf
bytes_written = snprintf(my_buf, MAX_LENGTH, "%d %d ...", arg0, arg1 ...);
Обратите внимание, что sprintf()
и варианты также требуют дополнительного байта для символа терминатора \0
так что это должно быть отражено в заданном вами размере буфера. Возвращаемое значение (количество записанных байтов) не включает символ-терминатор.