#c #pointers #long-integer
#c #указатели #длинное целое число
Вопрос:
Я совсем новичок в C, и у меня возник вопрос, когда я имею дело с длинными целыми числами / символами * в C. Я хочу сохранить long в char *, но я не уверен, как мне следует управлять размером моего буфера, чтобы соответствовать любому заданному long. Это то, что я хочу:
char buffer[LONG_SIZE]; // what should LONG_SIZE be to fit any long, not depending on the OS?
sprintf(buffer, "%ld", some_long);
Мне нужно использовать C, а не C . Есть ли какое-либо решение для этого, если я не хочу использовать магические числа?
Комментарии:
1. Количество цифр = количество бит / 3,32 1 для знака 1 для нулевого терминатора. Таким образом, для 32 бит требуется 12, для 64 требуется 22 и т.д.
Ответ №1:
если я не хочу использовать магические числа
Использование snprintf()
с буфером длиной 0 вернет количество символов, необходимое для хранения результата (минус конечный 0). Затем вы можете выделить достаточно места для хранения строки по требованию:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main(void) {
long some_long = LONG_MAX - 5;
// Real code should include error checking and handling.
int len = snprintf(NULL, 0, "%ld", some_long);
char *buffer = malloc(len 1);
snprintf(buffer, len 1, "%ld", some_long);
printf("%s takes %d charsn", buffer, len);
free(buffer);
}
Существует также asprintf()
, доступный в Linux glibc и некоторых BSD, который выделяет для вас результирующую строку с более удобным (но менее переносимым) интерфейсом, чем приведенный выше.
Выделение необходимого пространства по требованию вместо использования фиксированного размера имеет некоторые преимущества; он будет продолжать работать без дополнительной настройки, если вы измените строку формата в какой-то момент в будущем, например.
Даже если вы придерживаетесь буфера фиксированной длины, я рекомендую использовать snprintf()
over sprintf()
, чтобы убедиться, что вы каким-то образом не перезапишете буфер.
Ответ №2:
Вероятно, правильнее использовать snprintf
для вычисления необходимого размера, но, похоже, это должно сработать:
char buf[ sizeof(long) * CHAR_BIT ];
Ответ №3:
Количество битов в a long
равно sizeof long * CHAR_BIT
. ( CHAR_BIT
определяется в <limits.h>
.) Это может представлять не более знакового числа величиной 2 sizeof long * CHAR_BIT - 1
.
Такое число может содержать не более половины (log 10 2 sizeof long * CHAR_BIT - 1
) 1 десятичных цифр. Это floor( (sizeof long * CHAR_BIT - 1)
* log 10 2) 1. log 10 2 меньше .302, поэтому (sizeof long * CHAR_BIT - 1)
* 302 / 1000 1 байтов достаточно для цифр.
Добавьте один для знака и один для завершающего нулевого символа, и char[(sizeof long * CHAR_BIT - 1) * 302 / 1000 3]
этого достаточно для буфера.