Ответ 1
const int n = snprintf(NULL, 0, "%lu", ulong_value);
assert(n > 0);
char buf[n+1];
int c = snprintf(buf, n+1, "%lu", ulong_value);
assert(buf[n] == '\0');
assert(c == n);
На языке C, как мне преобразовать значение unsigned long в строку (char *) и сохранить мой исходный код переносимым или просто перекомпилировать его для работы на другой платформе (без перезаписи кода?
Например, если у меня есть sprintf(buffer, format, value)
, как определить размер буфера с независимым от платформы образом?
const int n = snprintf(NULL, 0, "%lu", ulong_value);
assert(n > 0);
char buf[n+1];
int c = snprintf(buf, n+1, "%lu", ulong_value);
assert(buf[n] == '\0');
assert(c == n);
Стандартным подходом является использование sprintf(buffer, "%lu", value);
для записи строкового представления value
в buffer
. Однако переполнение является потенциальной проблемой, так как sprintf
будет радостно (и неосознанно) писать в конце вашего буфера.
На самом деле это большая слабость sprintf, частично фиксированная на С++ с использованием потоков, а не буферов. Обычный "ответ" заключается в том, чтобы выделить очень щедрый буфер, который вряд ли переполнится, пусть это приведет к выводу sprintf, а затем использовать strlen для определения фактической длины строки, вызванной буфером (size size + 1) и скопировать строку в эту,
Этот сайт обсуждает эту и связанные с этим проблемы в некоторой степени.
Некоторые библиотеки предлагают snprintf
как альтернативу, которая позволяет указать максимальный размер буфера.
вы можете написать функцию, которая преобразует из unsigned long в str, аналогичную библиотечной функции ltostr.
char *ultostr(unsigned long value, char *ptr, int base)
{
unsigned long t = 0, res = 0;
unsigned long tmp = value;
int count = 0;
if (NULL == ptr)
{
return NULL;
}
if (tmp == 0)
{
count++;
}
while(tmp > 0)
{
tmp = tmp/base;
count++;
}
ptr += count;
*ptr = '\0';
do
{
res = value - base * (t = value / base);
if (res < 10)
{
* -- ptr = '0' + res;
}
else if ((res >= 10) && (res < 16))
{
* --ptr = 'A' - 10 + res;
}
} while ((value = t) != 0);
return(ptr);
}
вы можете сослаться на мой блог здесь, который объясняет реализацию и использование с примером.
char buffer [50];
unsigned long a = 5;
int n=sprintf (buffer, "%lu", a);
Попробуйте использовать sprintf
:
unsigned long x=1000000;
char buffer[21];
sprintf(buffer,"%lu", x);
Edit:
Обратите внимание, что вам необходимо заранее выделить буфер, и не знаешь, как долго будут на самом деле числа, когда вы это сделаете. Я предполагаю 32bit long
s, который может производить цифры размером до 10 цифр.
См. Carl Smotricz для лучшего объяснения затронутых проблем.
Для длинного значения вам нужно добавить информацию длины 'l' и 'u' для целых чисел без знака,
в качестве ссылки доступных опций см. sprintf
#include <stdio.h>
int main ()
{
unsigned long lval = 123;
char buffer [50];
sprintf (buffer, "%lu" , lval );
}