Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Форматирование числа (number_format) 
V
    Опции темы
suxxor
Дата 27.7.2011, 23:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 14.10.2010

Репутация: нет
Всего: нет



Есть число 1000000, нужно его отформатировать в 1,000,000

В общем, нужно создать аналог функции number_format (PHP)

Я написал что-то близкое (и оно даже работает), но нужно её максимально упростить (самое главное сделать БЕЗ рекурсии, как в примере)
или это самый оптимальный вариант
Код

// lNumber - входное число
// szBuffer - выходные данные
// bNew & iCount - для рекурсивной работы

void number_format(ULONGLONG lNumber, wchar_t* szBuffer, bool bNew, int iCount)
{
    if(lNumber <= 0)
    {
        *szBuffer = L'0';
        return;
    }

    static int iCnt = 0;
    static wchar_t cHex[] = L"0123456789";

    if(bNew)
        iCnt = 0;

    ULONGLONG lCheckDec = lNumber / 10;

    if(lCheckDec > 0)
        number_format(lCheckDec, szBuffer, FALSE, iCount + 1);

    szBuffer[iCnt] = (lNumber % 10)[cHex];

    if(iCount && !(iCount % 3))
    {
        szBuffer[iCnt + 1] = L',';
        iCnt += 2;
    }
    else
    {
        iCnt++;
    }
}


Может есть готовые решения на С++ (с использованием STL/CRT или ещё чего, только без MFC)


Это сообщение отредактировал(а) suxxor - 27.7.2011, 23:36
PM   Вверх
baldina
Дата 28.7.2011, 01:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Код

iCnt=0;
while (lNumber > 0)
{
      if ((iCnt+1)%(4+iCnt/(4+iCnt))== 0)
        szBuffer[iCnt++] = ',';
      szBuffer[iCnt++] = (lNumber % 10)[cHex];
      lNumber /= 10;
}


Добавлено @ 01:51
ну и перевернуть строку

Это сообщение отредактировал(а) baldina - 28.7.2011, 02:20
PM MAIL   Вверх
volatile
Дата 28.7.2011, 02:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(baldina @  28.7.2011,  01:51 Найти цитируемый пост)
 if ((iCnt+1)%(4+iCnt/(4+iCnt))== 0)

а зачем такое условие, вроде достаточно
Код

if ((iCnt+1)%4 == 0)


Цикл лучше сделать 
do { 
  ... 
} while (lNumber);
а то 0 не выведет.

И в самом конце строку не забыть терминировать.
szBuffer[iCnt] = 0;
PM MAIL   Вверх
suxxor
Дата 28.7.2011, 06:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 14.10.2010

Репутация: нет
Всего: нет



О, посоны, я вас люблю!

Сделал так, вроде всё правильно, если чё не так укажите!
Код

#ifndef UNICODE
#define UNICODE
#endif

#include <windows.h>
#include <stdio.h>
#include <conio.h>

bool number_format(ULONGLONG lNumber, wchar_t* szBuffer)
{
    if(lNumber <= 0)
        return 0;

    int iCnt = 0;
    wchar_t cHex[] = L"0123456789";
    wchar_t* szReturn = szBuffer;

    do
    {
        if((iCnt + 1) % 4 == 0)
            szReturn[iCnt++] = ',';

        szReturn[iCnt++] = (lNumber % 10)[cHex];

        lNumber /= 10;
    }
    while(lNumber);

    szReturn[iCnt + 1] = '\0';
    szBuffer = wcsrev(szReturn);

    return 1;
}

int main()
{
    wchar_t format[20] = L"\0";
    long number = 1000000;

    number_format(number, format);

    wprintf(L"%i\n%s", number, format);

    while(!getch());
}


Это сообщение отредактировал(а) suxxor - 28.7.2011, 06:30
PM   Вверх
borisbn
Дата 28.7.2011, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(suxxor @  28.7.2011,  06:29 Найти цитируемый пост)
если чё не так укажите!

1.
Цитата

  if(lNumber <= 0)
        return 0;

сравнивать ULONGLONG на предмет меньше ли оно нуля не имеет смысла, а сам нуль чем не число ???
Код

  if ( lNumber == 0 )
  {
      szBuffer[ 0 ] = L'0';
      szBuffer[ 1 ] = 0;
      return true;
   }

2.
Цитата
szReturn[iCnt++] = L',';

это непринципиально, но так будет правильней.
3.
И потом, я бы этот знак передавал бы в параметрах, а по-умолчанию сделал бы ',':
Код

bool number_format(ULONGLONG lNumber, wchar_t* szBuffer, wchar_t separator = L',' )
{
...
        if((iCnt + 1) % 4 == 0)
            szReturn[iCnt++] = separator;
...
}

int main()
{
    wchar_t format1[20] = L"\0";
    wchar_t format2[20] = L"\0";
    long number = 1000000;

    number_format( number, format1, L'.' );
    number_format( number, format2 );

    wprintf( L"%i\n%s\n", number, format1 );
    wprintf( L"%i\n%s\n", number, format2 );
...



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
borisbn
Дата 28.7.2011, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



а вот рабочий вариант не привязанный к windows'у
http://liveworkspace.org/code/67370a62a951...ef8428df42ea5c2


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
spyswamp
Дата 28.7.2011, 11:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 349
Регистрация: 18.8.2006

Репутация: 1
Всего: 7



stringstream + locale и не надо никаких велосипедных циклов, вы чего.


--------------------
- why you call it beta?
- cuz it's betta then nothin'
PM MAIL   Вверх
suxxor
Дата 28.7.2011, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 14.10.2010

Репутация: нет
Всего: нет



Цитата(spyswamp @ 28.7.2011,  11:34)
stringstream + locale и не надо никаких велосипедных циклов, вы чего.

Хммм.... пример приведи

borisbn, спасибо

а как поступать с отрицательными числами?  if(lNumber < 0) тогда сохраняем значение отрицательности и на выходе прибавляем к началу szBuffer минус, как это реализовать?

Это сообщение отредактировал(а) suxxor - 28.7.2011, 11:45
PM   Вверх
spyswamp
Дата 28.7.2011, 11:55 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 349
Регистрация: 18.8.2006

Репутация: 1
Всего: 7



suxxor, http://stackoverflow.com/questions/4163243...-separator-in-c читани для разгона.

Добавлено через 12 минут и 3 секунды
suxxor, а потом это http://blog.p-jansson.com/2011/02/grouping...rator-in-c.html - более гибкий подход.


--------------------
- why you call it beta?
- cuz it's betta then nothin'
PM MAIL   Вверх
spyswamp
Дата 28.7.2011, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 349
Регистрация: 18.8.2006

Репутация: 1
Всего: 7



Вот еще текст: http://en.allexperts.com/q/C-1040/2008/8/T...d-Separator.htm Хотя, тут более общая информация про всю эту байду.


--------------------
- why you call it beta?
- cuz it's betta then nothin'
PM MAIL   Вверх
suxxor
Дата 28.7.2011, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 14.10.2010

Репутация: нет
Всего: нет



spyswamp, locale выдаст формат зависимый от настроек в ОС, если я не ошибаюсь
PM   Вверх
spyswamp
Дата 28.7.2011, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 349
Регистрация: 18.8.2006

Репутация: 1
Всего: 7



suxxor, ты инфу по ссылкам почитал (в особенность по второй)?


--------------------
- why you call it beta?
- cuz it's betta then nothin'
PM MAIL   Вверх
suxxor
Дата 28.7.2011, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 14.10.2010

Репутация: нет
Всего: нет



да короче, трудно мне с шаблонами STL работать, очень трудно ;( 
По мне лучше этот вариант

Это сообщение отредактировал(а) suxxor - 28.7.2011, 14:40
PM   Вверх
bsa
Дата 29.7.2011, 11:36 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(suxxor @  28.7.2011,  14:40 Найти цитируемый пост)
да короче, трудно мне с шаблонами STL работать

Если трудности вызваны не запретом начальства, то стоит взять книжку и почитать о STL. Нет в нем ничего сложного. Просто подход несколько неожиданный для классического программиста.

Это сообщение отредактировал(а) bsa - 29.7.2011, 11:38
PM   Вверх
suxxor
Дата 2.8.2011, 00:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 14.10.2010

Репутация: нет
Всего: нет



bsa, проблем  начальством нет - потому что начальства нет... Учу по книге STL для профессионалов от Николая Джусьютиса, всё никак ниасилю
PM   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0709 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.