Как конвертировать unsigned long в строку - PullRequest
18 голосов
/ 25 апреля 2010

На языке C, как преобразовать значение unsigned long в строку ( char *) и сохранить переносимый исходный код или просто перекомпилировать его для работы на другой платформе ( без переписывания кода?

Например, если у меня есть sprintf(buffer, format, value), как определить размер буфера независимым от платформы способом?

Ответы [ 6 ]

26 голосов
/ 26 апреля 2010
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);
6 голосов
/ 26 апреля 2010

Стандартный подход заключается в использовании sprintf(buffer, "%lu", value); для записи строкового повторения от value до buffer. Тем не менее, переполнение является потенциальной проблемой, так как sprintf будет радостно (и неосознанно) записывать поверх конца вашего буфера.

Это на самом деле большая слабость sprintf, частично исправленная в C ++ с использованием потоков, а не буферов. Обычный «ответ» - выделить очень большой буфер, который вряд ли переполнится, позволить выводить sprintf, а затем использовать strlen для определения фактической длины полученной строки, вызвать буфер (такого размера + 1) и скопировать строку ,

Этот сайт довольно подробно обсуждает эту и связанные с ней проблемы.

Некоторые библиотеки предлагают snprintf в качестве альтернативы, которая позволяет указать максимальный размер буфера.

5 голосов
/ 03 марта 2013

вы можете написать функцию, которая преобразует из 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);
}

Вы можете обратиться к моему блогу здесь , который объясняет реализацию и использование с примером.

2 голосов
/ 26 апреля 2010

Попробуйте использовать sprintf:

unsigned long x=1000000;
char buffer[21];
sprintf(buffer,"%lu", x);

Edit:

Обратите внимание, что вам нужно заранее выделить буфер, и вы не знаете, сколько на самом деле будут эти цифры. Я предполагаю, что 32-битный long с, который может производить числа до 10 цифр.

См. Ответ Карла Смотрица для лучшего объяснения проблем.

2 голосов
/ 26 апреля 2010
char buffer [50];

unsigned long a = 5;

int n=sprintf (buffer, "%lu", a);
0 голосов
/ 26 апреля 2010

Для длинных значений вам нужно добавить информацию о длине 'l' и 'u' для десятичного целого числа без знака,

в качестве ссылки на доступные опции см. sprintf

#include <stdio.h>

    int main ()
    {
      unsigned long lval = 123;
      char buffer [50];
      sprintf (buffer, "%lu" , lval );
     }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...