Вставка ведущих нулей в целое число - PullRequest
1 голос
/ 10 ноября 2009

У меня есть функция в C, которая генерирует количество часов из периферийного устройства rtc, которое я затем хочу заполнить массивом внутри объекта struct. Массив настроен на 5 цифр, но мне нужно добавить начальные нули к числу, если оно меньше 5 цифр.

Может ли кто-нибудь посоветовать простой способ достижения этого?

Ответы [ 9 ]

12 голосов
/ 10 ноября 2009
char array[5];
snprintf(array, 5, "%05d", number)
1 голос
/ 10 ноября 2009

Пара небольших подпрограмм, которые будут делать то, что вы хотите, без библиотеки printf(). Обратите внимание, что у подпрограмм нет способа сказать вам, что переданный вами int слишком велик для переданного размера буфера - я оставлю это добавление в качестве упражнения для читателя. Но они безопасны от переполнения буфера (если я не оставил там ошибку).

void uint_to_str_leading( char* dst, unsigned int i, size_t size )
{
    char* pCurChar;

    if (size == 0) return;

    pCurChar = dst + size;  // we'll be working the buffer backwards

    *--pCurChar = '\0';   // take this out if you don't want an ASCIIZ output
                          //   but think hard before doing that...

    while (pCurChar != dst) {        
        int digit = i % 10;
        i = i /10;

        *--pCurChar = '0' + digit;
    }

    return;
}


void int_to_str_leading( char* dst, int i, size_t size )
{
    if (size && (i < 0)) {
        *dst++ = '-';
        size -= 1;

        i *= -1;
    }

    uint_to_str_leading( dst, i, size);

    return;
}

Обратите внимание, что эти подпрограммы передают размер буфера и заканчиваются символом '\ 0', так что ваши результирующие строки будут иметь на один символ меньше размера, который вы передали (так что не просто передавайте размер поля ищем).

Если вам не нужен завершающий символ '\ 0', потому что вы имеете дело с фиксированным массивом char [], который не завершен, то достаточно просто извлечь одну строку кода, которая выполняет завершение (но, пожалуйста, рассмотрите возможность завершения массива char [] - если вы этого не сделаете, держу пари, вы увидите по крайней мере одну ошибку, связанную с этим, в течение следующих 6 месяцев).

Изменить, чтобы ответить на несколько вопросов:


dst - указатель на буфер назначения. Вызывающая сторона должна иметь место для размещения строки, созданной функцией, во многом как стандартная библиотечная функция strcpy().

Указатель pCurChar - это указатель на местоположение, куда пойдет следующий произведенный цифровой символ. Он используется немного по-другому, чем большинство символьных указателей, потому что алгоритм начинается в конце буфера и движется к началу (это потому, что мы получаем цифры от «конца» целого числа). На самом деле, pCurChar указывает сразу за тем местом в буфере, куда он собирается поместить следующую цифру. Когда алгоритм добавляет цифру в буфер, он уменьшает указатель , прежде чем разыменовывает его. Выражение:

*--pCurChar = digit;

Эквивалентно:

pCurChar = pCurChar-1;  /* move to previous character in buffer */
*pCurChar = digit;

Он делает это, потому что проверка того, когда мы закончим, это:

while (pCurChar == dst) {   /* when we get to the start of the buffer we're done */

Вторая функция - это простая процедура, которая обрабатывает целые числа со знаком, превращая отрицательные числа в положительные и позволяя 1-й функции выполнять всю настоящую работу, например:

  • помещая символ '-' в начале буфера,
  • настройка указателя и размера буфера и
  • отрицание числа, чтобы сделать его положительным
  • передача этого значения в функцию, которая преобразует целое число без знака для выполнения реальной работы

Пример использования этих функций:

char buffer[80];

uint_to_str_leading( buffer, 0, 5); 
printf( "%s\n", buffer);

uint_to_str_leading( buffer, 123, 6); 
printf( "%s\n", buffer);

uint_to_str_leading( buffer, UINT_MAX, 14); 
printf( "%s\n", buffer);

int_to_str_leading( buffer, INT_MAX, 14); 
printf( "%s\n", buffer);

int_to_str_leading( buffer, INT_MIN, 14); 
printf( "%s\n", buffer);

Который производит:

0000
00123
0004294967295
0002147483647
-002147483648
1 голос
/ 10 ноября 2009

как и решение @ Аарона, единственный способ сделать это в C - это трактовать его как символ вместо числа. Лидирующие нули игнорируются, когда они встречаются как значения, и указывают восьмеричную константу при появлении в коде.

int a = 0000015; // translates to decimal 13.
0 голосов
/ 10 ноября 2009

извинения за отсутствие деталей. Мой код генерирует 32-разрядное целое число, которое я ожидаю получить только до 5 десятичных цифр в размере. Затем я вызываю функцию:

numArray = numArrayFill(12345, buf, sizeof(buf));

(uint32_t number, char *buffer, int size) 
{
    char *curr = &buffer[size];             
    *--curr = 0;                            
    do 
    {
        *--curr = (number % 10) + '0';
        number /= 10;
    } 
    while (number != 0);

    if (curr == buffer && number != 0)      
    return NULL;

    return curr;
}   

Проблема возникает, когда я набираю менее 5 цифр и получаю случайное поведение. Что мне нужно сделать, это добавить нули к передней части, чтобы это всегда было 5-значное число.

Спасибо Дэйв

0 голосов
/ 10 ноября 2009
int newNumber [5]  = 0;

for ( int i=0; givenNumber != 0 && i < 5 ; i++ ) {
    newNumber[i] = givenNumber%10;
    givenNumber = givenNumer/10;
}
0 голосов
/ 10 ноября 2009

Вас не устраивает простой total bzero () или что-то в этом роде, а затем заполнение новым значением? Не могли бы вы описать более подробно, если нет?

Я не шучу, я видел несколько случаев, когда полное заполнение с 0 быстрее, чем трюки с добавлением 0, особенно, если память была кэширована и bzero () имела некоторую поддержку пакетной записи.

0 голосов
/ 10 ноября 2009

попробуйте это:

    char source[5+1] = { '1','2', 0, 0, 0, 0 };
    char dest[5+1];
    int nd = strlen(source) ;
    memset ( dest, '0', 5 - nd );
    sprintf ( dest+nd+1, "%s", source );
0 голосов
/ 10 ноября 2009

Если тип int, то нет. Установить тип в строку?

0 голосов
/ 10 ноября 2009

Инициализируйте каждый элемент в массиве до 0 перед вставкой цифр в массив. Таким образом, вы всегда будете иметь 5 цифр с ведущими нулями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...