Перейти к содержанию
    

Здравствуйте, Вопрос к людям хорошо знающим С.

Понадобилась функция перевода целого числа в строку. Перерыл спрвочник и help - результат 0.

Банальная проблема. Увы. Обраных функций вагон.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тут или пользоваться sprintf (или её вариантами - смотреть в описании Вашего компилятора) или утянуть откуда-нибудь (я в свой проект включил часть исходников библиотечных функций - под именем НЕ совпадающим с библиотечным).

В книге K&R есть пример функции - переделайте под вывод в строку.

 

Или вот ещё - как можно поступить, если под рукой нет зубной щётки:

 

void lcd_menu_value(
    unsigned long freq,
    uint_least8_t width,    // full width
    uint_least8_t comma,        // comma position (from right, inside width)
    uint_least8_t rj        // right truncated
    )
{
    static const prog_uint32_t vals [] =
    {
        100000000,
        10000000,
        1000000,
        100000,
        10000,
        1000,
        100,
        10,
        1,
    };
    const unsigned  char j = (sizeof vals /sizeof vals [0]) - rj;
    unsigned  char i = (j - width);
    unsigned  char z = 1;    // only zeroes


    for (; i < j; ++ i)
    {
        ldiv_t res = ldiv(freq, pgm_read_dword(& vals [i]));

        if (comma == (j - i))
        {
            z = 0;
            ws1602_wrdata('.');
        }
        if (z == 1 && (i + 1) < j && res.quot == 0)
            ws1602_wrdata(' ');    // supress zero
        else
        {
            z = 0;
            ws1602_wrdata('0' + res.quot);
        }
        freq = res.rem;
    }
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В свое время я задавал такой же вопрос. Получил несколько ответов, в том числе и не очень "полезных и приятных". Сам написал такое:

void si16toad (int16_t Number, char * StrBuf)
{
  char Sign = ' ';
  if (Number > 0) Sign = '+';
  if (Number < 0) {
    Sign = '-';
    Number = -Number;
  }
  StrBuf[6] = '\0';
  signed char i = 5;
  do {
    StrBuf[i--] = Number % 10 + '0';
    Number /= 10;
  } while (Number);
  StrBuf[i] = Sign;
  for (i--; i >= 0; i--) StrBuf[i] = ' ';
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сам написал такое

Совет - больше никому "такое" не показывайте, ну если только врагам.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Совет - больше никому "такое" не показывайте, ну если только врагам.

Что же в этой функции такого плохого?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В свое время я задавал такой же вопрос. Получил несколько ответов, в том числе и не очень "полезных и приятных". Сам написал такое:

тяжеловесно и потенциально опасно в смысле стрельбы по памяти

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Совет - больше никому "такое" не показывайте, ну если только врагам.

Я хотел приписать, что это один из первых моих "опусов", но подумал, что в качестве примера для изучения сгодится.

Если можете выдать "достойный" образец, прошу!

P.S. У меня знак рисуется непосредственно перед числом, выравнивается по правому краю. А, ну да, можно было применить указатель, но тогда не пришло в голову.

P.P.S. Господа, давайте найдем, наконец, лучшее решение. А то, сколько людей, столько и мнений. Да, я помню высказывание zltigo, что тема избита. Однако...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что же в этой функции такого плохого?

Абсолютно все :(. Написано на уровне диалекта "Эллочки людоедки", лишние действия, вычиcления, циклы.

 

давайте найдем, наконец, лучшее решение.

А что такое лучшее? Гуано оно всегда гуано, а лучшее, как минимум требует критериев для оценки. Если, например, скорость, то для AVR и 16bit чисел уж точно делений быть не должно, тем более громоздкого сочетания деления и взятия остатка от деления.

А тема, действительно, избитая донельзя. Повторять мамнадцатый раз не вижу смысла.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...лишние действия, вычиcления, циклы...

Оставил только значимую часть сообщения :)

Лучший способ воспитания - на собственном примере.

Покажите, как надо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Оставил только значимую часть сообщения :)

Лучший способ воспитания - на собственном примере.

Покажите, как надо.

Особенно интересно, как можно это реализовать без циклов :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Просто как пример:

unsigned int short2str(char *str, unsigned short v, unsigned int slz)
{
    unsigned int a, b, n = 0;
    unsigned long vi;

    vi = v * 26844UL;
    if(v >= 57074) vi -= 13422;    // Вдруг кто скопипастит без проверки
    for(a = 0; a < 5; a++)
    {
        b = vi >> 28;
        if(b || !slz)
        {
            *str++ = b + '0';
            n++;
            slz = 0;
        }
        vi &= ~(0x0f << 28);
        vi *= 10;
    }
    if(!n)
    {
        *str++ = '0';
        n = 1;
    }
    *str++ = 0;
    return n;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

лучшее, как минимум требует критериев для оценки

Я писал для STM32. Виноват, не сказал сразу. Для PIC или AVR написал бы другое "гуано" :)

Критериев, собственно, два - высокое быстродействие и минимальный объем кода. Понятно, что это две крайности, а лучшее лежит где-то посередине.

У вас есть что-нибудь для ARM - Cortex?

И, если можно, выскажитесь о первом примере от Genadi Zawidowsky. И о последующих.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Особенно интересно, как можно это реализовать без циклов :)

Ну для этого сначала нужно понимать русский языка, в частности различие между единственным (цикл)и множественным числом (циклы). В данном конкретном случае, когда по неведомым причинам формат фиксирован 6 символами и используются страшные / и % не нужен и единственный цикл.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В данном конкретном случае, когда по неведомым причинам формат фиксирован 6 символами и используются страшные / и % не нужен и единственный цикл.

int16 укладывается в эти 6 символов, со знаком, ни больше, ни меньше.

В первом цикле вычисляются цифры, во втором забивал пробелами оставшееся место слева. Можно было сразу инициализировать массив пробелами, но было бы ли это эффективнее?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

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

×
×
  • Создать...