Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Сумма прописью


Автор: binpol 7.6.2008, 19:13
У меня есть вопрос, как сделать сумму прописью если допустим в один Edit вставить сумму цифрами, а сумма прописью чтобы появилась во втором Edit и с копейками, например 100,55 (Сто рублей пятьдесят пять копеек)

Автор: Jorjio 7.6.2008, 20:11
Вообще наверное можно сделать массив
const char * number [] = 
         {"ноль", "один", "два", "три", "четыре", 
        "пять", "шесть", "семь", "восемь", "девять"}; 

Проверять цифровой эдит посимвольно, формировать строку
только получится криво. smile

Добавлено через 1 минуту и 17 секунд
(100,10) один ноль ноль рублей один ноль копеек smile 

Автор: fish9370 7.6.2008, 22:35
Цитата(Jorjio @ 7.6.2008,  20:11)
Вообще наверное можно сделать массив
const char * number [] = 
         {"ноль", "один", "два", "три", "четыре", 
        "пять", "шесть", "семь", "восемь", "девять"}; 

Проверять цифровой эдит посимвольно, формировать строку
только получится криво. smile

Добавлено @ 20:13
(100,10) один ноль ноль рублей один ноль копеек smile

в целом идея правильная, только нужно добавить в массив такие величины:
еденицы, десятки, сотни, тысячи, миллионы и миллиарды..

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

Автор: Dmi3ev 7.6.2008, 22:36
Jorjio, массив тут не при чем, я недавно столкнулся с такой проблемой и нашел такое решение, приведу пример для единиц и десятков копеек.
Код

AnsiString edk(int bvk)
{
AnsiString res="";//возвращаемое значение
int q, r;//частное и остаток
q=div(bvk, 10).quot;
r=div(bvk, 10).rem;
if (q!=1)
{
 switch (r)
  {
   case 1: res="одна"; break;
   case 2: res="две"; break;
   case 3: res="три"; break;
   case 4: res="четыре"; break;
   case 5: res="пять"; break;
   case 6: res="шесть"; break;
   case 7: res="семь"; break;
   case 8: res="восемь"; break;
   case 9: res="девять"; break;
  }
}
else
 res="";
return (res);
}
//---------------------------------------------------------------------------
AnsiString des (int inp)
{
AnsiString res="";//возвращаемое значение
int q, r;//частное и остаток
q=div(inp, 10).quot;
r=div(inp, 10).rem;
if (q==0) return ("");
switch (q)
 {
  case 1:
  switch (r)
   {
    case 0: res="десять"; break;
    case 1: res="одиннадцать"; break;
    case 2: res="двенадцать"; break;
    case 3: res="тринадцать"; break;
    case 4: res="четырнадцать"; break;
    case 5: res="пятнадцать"; break;
    case 6: res="шестнадцать"; break;
    case 7: res="семнадцать"; break;
    case 8: res="восемнадцать"; break;
    case 9: res="девятнадцать"; break;
   }
  break;
  case 2: res="двадцать"; break;
  case 3: res="тридцать"; break;
  case 4: res="сорок"; break;
  case 5: res="пятьдесят"; break;
  case 6: res="шестьдесят"; break;
  case 7: res="семьдесят"; break;
  case 8: res="восемдесят"; break;
  case 9: res="девяносто"; break;
 }
return (res);
}

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

Добавлено через 1 минуту и 19 секунд
хотя массив тоже можно использовать)))

Автор: Jorjio 8.6.2008, 08:49
Dmi3ev
Если действительно задаться целью создания именно такой программы как задано решение можно найти любое
только идти надо, действительно вот куда
Цитата

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

Автор: Dmi3ev 10.6.2008, 01:01
я писал не для денег, но вот немного переделанный вариант для конкретного случая
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#include <myround.h>//моя функция на основе floor и ceil из <math.h>
#pragma hdrstop

#include "money_U.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
AnsiString edk(int bvk)
{
AnsiString res="";//возвращаемое значение
int q, r;//частное и остаток
q=div(bvk, 10).quot;
r=div(bvk, 10).rem;
if (q!=1)
{
 switch (r)
  {
   case 1: res="одна"; break;
   case 2: res="две"; break;
   case 3: res="три"; break;
   case 4: res="четыре"; break;
   case 5: res="пять"; break;
   case 6: res="шесть"; break;
   case 7: res="семь"; break;
   case 8: res="восемь"; break;
   case 9: res="девять"; break;
  }
}
else
 res="";
return (res);
}
//---------------------------------------------------------------------------
AnsiString des (int inp)
{
AnsiString res="";//возвращаемое значение
int q, r;//частное и остаток
q=div(inp, 10).quot;
r=div(inp, 10).rem;
if (q==0) return ("");
switch (q)
 {
  case 1:
  switch (r)
   {
    case 0: res="десять"; break;
    case 1: res="одиннадцать"; break;
    case 2: res="двенадцать"; break;
    case 3: res="тринадцать"; break;
    case 4: res="четырнадцать"; break;
    case 5: res="пятнадцать"; break;
    case 6: res="шестнадцать"; break;
    case 7: res="семнадцать"; break;
    case 8: res="восемнадцать"; break;
    case 9: res="девятнадцать"; break;
   }
  break;
  case 2: res="двадцать"; break;
  case 3: res="тридцать"; break;
  case 4: res="сорок"; break;
  case 5: res="пятьдесят"; break;
  case 6: res="шестьдесят"; break;
  case 7: res="семьдесят"; break;
  case 8: res="восемдесят"; break;
  case 9: res="девяносто"; break;
 }
return (res);
}
//---------------------------------------------------------------------------
AnsiString kop (int bvk)
{
AnsiString res=des(bvk)+" "+edk(bvk);
if (res==" ")
 return("ноль коп.");
else
 return (res+" коп.");
}
//---------------------------------------------------------------------------
AnsiString edr(int bvr)
{
AnsiString res="";//возвращаемое значение
int q, r;//частное и остаток
q=div(bvr, 10).quot;
r=div(bvr, 10).rem;
if (q!=1)
{
 switch (r)
  {
   case 1: res="один"; break;
   case 2: res="два"; break;
   case 3: res="три"; break;
   case 4: res="четыре"; break;
   case 5: res="пять"; break;
   case 6: res="шесть"; break;
   case 7: res="семь"; break;
   case 8: res="восемь"; break;
   case 9: res="девять"; break;
  }
}
else
 res="";
return (res);
}
//---------------------------------------------------------------------------
AnsiString sot (int bvr)
{
AnsiString res="";
int q=div(bvr, 100).quot;
if (q!=0)
 {
  switch (q)
   {
    case 1: res="сто"; break;
    case 2: res="двести"; break;
    case 3: res="триста"; break;
    case 4: res="четыреста"; break;
    case 5: res="пятьсот"; break;
    case 6: res="шестьсот"; break;
    case 7: res="семьсот"; break;
    case 8: res="восемьсот"; break;
    case 9: res="девятьсот"; break;
   }
  return (res+" ");
 }
else
 return ("");
}
//---------------------------------------------------------------------------
AnsiString tis (int bvr)
{
AnsiString res=sot((bvr%1000000)/1000)+des((bvr%100000)/1000)+" "+edk((bvr%100000)/1000);
if (res==" ")
 return("");
else
 return (res+" тыс.");
}
//---------------------------------------------------------------------------
AnsiString rub (int bvr)
{
AnsiString res=tis(bvr)+" "+sot(bvr%1000)+des(bvr%100)+" "+edr(bvr%100);
if (res==" ")
 return("ноль руб.");
else
 return (res+" руб.");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString r, k;
r=k=0;
double bv=(Edit1->Text).ToDouble();//исходное число
int bvr, bvk;//рубли и копейки
bvr=bvk=0;
bvr=int(bv);
double h=0;
h=(bv-int(bv))*100;
bvk=myround(h);
k="";
r=rub(bvr);//рубли
k=kop(bvk);//копейки
Edit2->Text=r+" "+k;
k="";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key)
{
if ((Key>='0') && (Key<='9'))
 return;
if (Key==DecimalSeparator)
 {
  if ((Edit1->Text).Pos(DecimalSeparator)!=0)
   Key=0;
  return;
 }
if (Key==VK_BACK)
 return;
if (Key==VK_RETURN)
 {
  Button1->SetFocus();
  return;
 }
Key=0;
}
//---------------------------------------------------------------------------

у меня была проблема с округлением (когда были большие числа была маленькая погрешность), тогда я не знал, как от нее избавиться, поэтому создал свою функцию:
Код

#include "math.h"

int myround (double h)
{
if (h>=(int(h)+0.5))
 h=ceil(h);
else
 h=floor(h);
return (h);
}

чуть-чуть доделать и будет неплохая прога smile 

Автор: fish9370 12.6.2008, 00:03
Цитата(Dmi3ev @  10.6.2008,  01:01 Найти цитируемый пост)
чуть-чуть доделать и будет неплохая прога 


я тут чуть-чуть доделал:

Код

//$$---- Form CPP ----
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

// don't remove this header
// date: 12.06.08
// author: fish9370

TForm1 *Form1;

const int MORPH_TYPE_NONE =    0;
const int MORPH_TYPE_NUM =        1;
const int MORPH_TYPE_THOUSAND = 2;
const int MORPH_TYPE_MILLION =    3;
const int MORPH_TYPE_BILLION =    4;

const int MORPH_SEX_FML    = 0;
const int MORPH_SEX_ML    = 1;

const int MORPH_TYPE_RUB =    6;
const int MORPH_TYPE_RKOP =    7;
const int MORPH_TYPE_USD =    8;
const int MORPH_TYPE_UCNT =    9;
const int MORPH_TYPE_EUR =    10;
const int MORPH_TYPE_ECNT =    11;

const int DGT_POS_00X = 0;
const int DGT_POS_0X0 = 1;
const int DGT_POS_X00 = 2;

const int SPL_HI = 0;
const int SPL_LO = 1;

class _DigToStr
{
    TStringList *sz1;    // 000 000 000 00X единицы
    TStringList *sz2;    // 000 000 000 0X0 десятки
    TStringList *sz3;    // 000 000 000 X00 сотни
    TStringList *sz4;    // 000 000 00X 000 тысячи

    TStringList *sz7;    // единицы измерения, старшие
    TStringList *sz8;    // единицы измерения, младшие
    
    AnsiString triad(int nD, int nPos, int nSex)
    {
        switch(nPos)
        {
            case DGT_POS_00X:
                if(nD<20)
                    return morph(sz1->Strings[nD], MORPH_TYPE_NUM, nSex, nD);
                break;
            case DGT_POS_0X0:
                return sz2->Strings[nD];
            case DGT_POS_X00:
                return sz3->Strings[nD];
        }

        return (AnsiString)"";
    }
public:
    _DigToStr()
    {
        sz1 = new TStringList;
        sz1->Add("");                // 0
        sz1->Add("од");              // 1
        sz1->Add("дв");          // 2
        sz1->Add("три");           // 3
        sz1->Add("четыре");          // 4
        sz1->Add("пять");            // 5
        sz1->Add("шесть");         // 6
        sz1->Add("семь");            // 7
        sz1->Add("восемь");          // 8
        sz1->Add("девять");          // 9
        sz1->Add("десять");          // 10
        sz1->Add("одинадцать");      // 11
        sz1->Add("двенадцать");      // 12
        sz1->Add("тринадцать");      // 13
        sz1->Add("четырнадцать");    // 14
        sz1->Add("пятнадцать");      // 15
        sz1->Add("шестнадцать");       // 16
        sz1->Add("семнадцать");      // 17
        sz1->Add("восемнадцать");    // 18
        sz1->Add("девятнадцать");    // 19

        sz2 = new TStringList;
        sz2->Add("");
        sz2->Add("десять");
        sz2->Add("двадцать");
        sz2->Add("тридцать");
        sz2->Add("сорок");
        sz2->Add("пятьдесят");
        sz2->Add("шестьдесят");
        sz2->Add("семьдесят");
        sz2->Add("восемьдесят");
        sz2->Add("девяносто");

        sz3 = new TStringList;
        sz3->Add("");
        sz3->Add("сто");
        sz3->Add("двести");
        sz3->Add("триста");
        sz3->Add("четыреста");
        sz3->Add("пятьсот");
        sz3->Add("шестьсот");
        sz3->Add("семьсот");
        sz3->Add("восемьсот");
        sz3->Add("девятьсот");

        sz4 = new TStringList;
        sz4->Add("тысяч");
        sz4->Add("миллион");
        sz4->Add("миллиард");

        sz7 = new TStringList;
        sz7->Add("рубл");
        sz7->Add("доллар");
        sz7->Add("евро");

        sz8 = new TStringList;
        sz8->Add("коп");
        sz8->Add("цент");
     sz8->Add("цент");
    }
    ~_DigToStr()
    {
        sz1->Free();
        sz2->Free();
        sz3->Free();
        sz4->Free();

        sz7->Free();
        sz8->Free();
    }
    AnsiString morph(AnsiString szWord, int nType, int nSex, int nVal)
    {
        AnsiString szA = szWord;
        switch(nType)
        {
            case MORPH_TYPE_NUM:
                switch(nVal)
                {
                    case 1:
                        if(nSex == MORPH_SEX_ML)
                            return szA + "ин";
                        else
                            return szA + "на";
                    case 2:
                        if(nSex == MORPH_SEX_ML)
                            return szA + "а";
                        else
                            return szA + "е";
                }
                break;
            case MORPH_TYPE_THOUSAND:
            {
                switch(nVal)
                {
                    case 1:
                        return szA + "а";
                    case 2:
                    case 3:
                    case 4:
                        return szA + "и";
                }
            }
            break;
            case MORPH_TYPE_MILLION:
            case MORPH_TYPE_BILLION:
            {
                switch(nVal)
                {
                    case 1:
                        return szA;
                    case 2:
                    case 3:
                    case 4:
                        return szA + "а";
                    default:
                        return szA + "ов";
                }
            }
            //break;

            case MORPH_TYPE_RUB:
                switch(nVal)
                {
                    case 1:
                        return szA + "ь";
                    case 2:
                    case 3:
                    case 4:
                        return szA + "я";
                    default:
                        return szA + "ей";
                }
            //break;
            case MORPH_TYPE_RKOP:
             switch(nVal)
                {
                    case 1:
                        return szA + "ейка";
                    case 2:
                    case 3:
                    case 4:
                        return szA + "ейки";
                    default:
                        return szA + "еек";
                }
            //break;
            case MORPH_TYPE_USD:
            case MORPH_TYPE_ECNT:
            case MORPH_TYPE_UCNT:
                switch(nVal)
                {
                    case 1:
                        return szA;
                    case 2:
                    case 3:
                    case 4:
                        return szA + "а";
                    default:
                        return szA + "ов";
                }
            //break;
            case MORPH_TYPE_EUR:
                switch(nVal)
                {
                    default:
                        return szA;
                }
            //break;
 
            default:
                return (AnsiString)"";
        }
        return szA;
    }

    AnsiString parsing(long nD, int nCurrency, int _nSex)
    {
        if(nD == 0)
         return (AnsiString)"";
        AnsiString szS, szA;

        szA = IntToStr(nD);
        int nVal;
        if(szA.Length() < 2)
            szA = szA.StringOfChar('0',2 - szA.Length()) + szA;
        if(szA[szA.Length() - 1] - 48 != 1)
            nVal = szA[szA.Length()] - 48;
        else
            nVal = szA.SubString(szA.Length() - 2,2).ToInt();

        switch(nCurrency)
        {
            case MORPH_TYPE_RUB:
                szS = " " + morph(sz7->Strings[0], MORPH_TYPE_RUB,0, nVal);
                break;
            case MORPH_TYPE_RKOP:
                szS = " " + morph(sz8->Strings[0], MORPH_TYPE_RKOP,0, nVal);
                break;
            case MORPH_TYPE_USD:
                szS = " " + morph(sz7->Strings[1], MORPH_TYPE_USD,0, nVal);
                break;
            case MORPH_TYPE_UCNT:
                szS = " " + morph(sz8->Strings[1], MORPH_TYPE_UCNT,0, nVal);
                break;
            case MORPH_TYPE_EUR:
                szS = " " + morph(sz7->Strings[2], MORPH_TYPE_EUR,0, nVal);
                break;
            case MORPH_TYPE_ECNT:
                szS = " " + morph(sz8->Strings[2], MORPH_TYPE_ECNT,0, nVal);
                break;
        }

        for(int i=1; nD; i++)
        {
            szA = IntToStr(nD % 1000);
            szA = szA.StringOfChar('0',3 - szA.Length()) + szA;

            int nSex, nVal;
            if(szA[2] - 48 != 1)
                nVal = szA[3] - 48;
            else
                nVal = szA.SubString(2,2).ToInt();

            if(szA != "000")
                switch(i)
                {
                    case MORPH_TYPE_NUM:
                            nSex = _nSex;
                        break;
                    case MORPH_TYPE_THOUSAND:
                        szS = " " + morph(sz4->Strings[0], MORPH_TYPE_THOUSAND, 0,nVal) + szS;
                        nSex = MORPH_SEX_FML;
                        break;
                    case MORPH_TYPE_MILLION:
                        szS = " " + morph(sz4->Strings[1], MORPH_TYPE_MILLION, 0,nVal) + szS;
                        nSex = MORPH_SEX_ML;
                        break;
                    case MORPH_TYPE_BILLION:
                        szS = " " + morph(sz4->Strings[2], MORPH_TYPE_BILLION, 0,nVal) + szS;
                        nSex = MORPH_SEX_ML;
                }

            if(szA[2] - 48 != 1)
            {
                szS = triad(szA[3] - 48, DGT_POS_00X, nSex) + szS;
                szS = " " + szS;
                szS = triad(szA[2] - 48, DGT_POS_0X0, nSex) + szS;
                szS = " " + szS;
                szS = triad(szA[1] - 48, DGT_POS_X00, nSex) + szS;
                szS = " " + szS;
            }
            else
            {
                szS = triad(szA.SubString(2,2).ToInt(), DGT_POS_00X, MORPH_SEX_ML) + szS;
                szS = " " + szS;
                szS = triad(szA[1] - 48, DGT_POS_X00, MORPH_SEX_ML) + szS;
                szS = " " + szS;
            }

            nD /= 1000;
        }

        return szS;
    }

    AnsiString split(AnsiString szWord, int nType)
    {
        if(szWord.Trim() == "")
            return (AnsiString)"";
        switch(nType)
        {
            case SPL_HI:
                if(szWord.Pos(","))
                    return szWord.SubString(0, szWord.Pos(",") - 1);
                else
                    return szWord;
            case SPL_LO:
                if(szWord.Pos(","))
                    return szWord.SubString(szWord.Pos(",") + 1,szWord.Length() - szWord.Pos(","));
        }
        return "0";
    }
    AnsiString toStr(AnsiString szWord, int nType)
    {
        switch(nType)
        {
            case MORPH_TYPE_RUB:
                return (parsing(split(szWord,SPL_HI).ToInt(),MORPH_TYPE_RUB, MORPH_SEX_ML) +
                    " " + parsing(split(szWord,SPL_LO).ToInt(),MORPH_TYPE_RKOP, MORPH_SEX_FML)).Trim();
            case MORPH_TYPE_USD:
                return (parsing(split(szWord,SPL_HI).ToInt(),MORPH_TYPE_USD, MORPH_SEX_ML) +
                    " " + parsing(split(szWord,SPL_LO).ToInt(),MORPH_TYPE_UCNT, MORPH_SEX_ML)).Trim();
            case MORPH_TYPE_EUR:
                return (parsing(split(szWord,SPL_HI).ToInt(),MORPH_TYPE_EUR, MORPH_SEX_ML) +
                    " " + parsing(split(szWord,SPL_LO).ToInt(),MORPH_TYPE_ECNT, MORPH_SEX_ML)).Trim();
        }
        return "ноль";
    }
};

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    _DigToStr D;
    Edit1->Text = D.toStr(Edit1->Text, MORPH_TYPE_RUB);
    //Edit1->Text = D.toStr(Edit1->Text, MORPH_TYPE_USD);
    //Edit1->Text = D.toStr(Edit1->Text, MORPH_TYPE_EUR);
}
//---------------------------------------------------------------------------

//todo:
//   добавить валидатор для проверки правильности ввода
//



Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)