[С++] перевод числа в пропись

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by cupper, 21 Sep 2009.

  1. cupper

    cupper Elder - Старейшина

    Joined:
    6 Jun 2007
    Messages:
    369
    Likes Received:
    92
    Reputations:
    5
    Lелал программку, одной из ее особенностей являлось необходимость вывода числа прописью (в моем случае это сумма в рублях до 999999999.99)(
    137098.37 = сто тридцать семь тсячь девяносто восемь рублей тридцать семь копеек). С горем пополам реализовал эту функциональность, на мой взгляд очень интересная фича, вот выкладываю код, может кому будет интересно или пригодится.

    Сразу предупреждаю - код убогий, зато работает.
    Code:
    string _rub (const int num){
           if ((num >= 5 && num <= 19) || num%10 == 0) return "рублей";
           else if (num >= 2 && num <= 4) return "рубля";
           else return "рубль";
           return "error";
    }
    string _cop (const int num){
           if ((num >= 5 && num <= 19) || num%10 == 0) return "копеек";
           else if (num >= 2 && num <= 4) return "копейки";
           else return "копейка";
           return "error";
    }
    string _thousands (const int num){
           if ((num >= 5 && num <= 19) || num%10 == 0) return "тысяч";
           else if (num >= 2 && num <= 4) return "тысячи";
           else return "тысяча";
           return "error";
    }
    string _millions (const int num){
           if ((num >= 5 && num <= 19) || num%10 == 0) return "миллионов";
           else if (num >= 2 && num <= 4) return "миллиона";
           else return "миллион";
           return "error";
    }
    map<int,string> digit1_19;
    string propis99 (const int num, const bool key = 0){
           if (num == 0) return "";
           string temp;
           if (key == 1){
              digit1_19[1]="одина"; // одна копейка
              digit1_19[2]="две"; // две тысячи
           }
           if (num > 0 && num < 20){
              temp=digit1_19[num];
              if (key == 1){
                 digit1_19[1]="один"; // один рубль 
                 digit1_19[2]="два"; // два миллиона
              }
              return temp.c_str();
           }
           else{
                if (num >= 20 && num <=39){
                   return (digit1_19[(num-num%10)/10]+"дцать "+digit1_19[num%10]).c_str();
                }
                else if (num >= 40 && num <=49){
                        return ("сорок "+digit1_19[num%10]).c_str();
                     }
                else if (num >= 50 && num <=89){
                        return (digit1_19[(num-num%10)/10]+"десят "+digit1_19[num%10]).c_str();
                     }
                else{
                     return ("девяносто "+digit1_19[num%10]).c_str();
                }
                return "FAIL";
           }
    }
    string propis999 (const int num, const bool key = 0){
           //if (num == 0) return "";
           if (num > 0 && num <100)
              return propis99(num, key);
           else if (num < 200){
                   return ("сто "+propis99(num%100, key));
                }
           else if (num < 300){
                   return ("двести "+propis99(num%100, key));
                }
           else if (num >=300 && num <500){
                   return (digit1_19[(num-num%100)/100]+"ста "+ propis99(num%100, key));
                }
           else{
                return (digit1_19[(num-num%100)/100]+"сот "+ propis99(num%100, key));
           }
           
    }
    const char* convert_to_str(const double num){
          //--------------------------------------
    digit1_19[1]="один";
    digit1_19[2]="два";
    digit1_19[3]="три";
    digit1_19[4]="четыре";
    digit1_19[5]="пять";
    digit1_19[6]="шесть";
    digit1_19[7]="семь";
    digit1_19[8]="восемь";
    digit1_19[9]="девять";
    digit1_19[10]="десять";
    digit1_19[11]="одиннадцать";
    digit1_19[12]="двенадцать";
    digit1_19[13]="тринадцать";
    digit1_19[14]="четырнадцать";
    digit1_19[15]="пятнадцать";
    digit1_19[16]="шестнадцать";
    digit1_19[17]="семьнадцать";
    digit1_19[18]="восемьнадцать";
    digit1_19[19]="девятнадцать";
           //--------------------------------------
           if (num > 999999999.99) return "превышена максимальная сумма в 999,999,999.99 рублей";
           string str, str1;
           const int RUB = (int)num;
           const int COP = (int)((num - RUB)*100);
           int tempr1=RUB, tempr2; // в tempr2 храниться посление одно-два-три числа от оставшегося числа
           int keyH=0; // если выше 0 то значит пора делать приписки 1 - тысячи, 2 - миллионы
           if (RUB == 0){str+="ноль ";}
           else{
                while (tempr1 > 0){
                      /*вычленяем по три-две-одной цифре и распознаем их, до тех пор пока цивры некончаться*/
                      tempr2=tempr1%1000;
                      if (tempr2 != 0){
                      if (tempr2%10 == 1 || tempr2%10 == 2) str1=propis999(tempr2, 1)+" ";
                      else str1=propis999(tempr2)+" ";
                      if (keyH == 1){
                         if (tempr2%100 > 10 && tempr2%100 < 20)str1+=_thousands(tempr2%100)+" ";
                         str1+=_thousands(tempr2%10)+" ";
                      }
                      if (keyH == 2){
                          if (tempr2%100 > 10 && tempr2%100 < 20)str1+=_millions(tempr2%100)+" ";
                         str1+=_millions(tempr2%10)+" ";
                      }
                      str1+=str;
                      str=str1;
                      }
                      tempr1=(tempr1-tempr2)/1000;
                      ++keyH;
                }
           }
           if (RUB%100 > 10 && RUB%100 < 20) str+=_rub(11)+" ";
           else str+=_rub(RUB%10)+" ";
           if (COP == 0){str+="ноль ";}
           else if (COP%10 == 1 || COP%10 == 2) str+=propis999(COP, 1)+" ";
           else str+=propis999(COP)+" ";
           if (COP%100 > 10 && COP%100 < 20) str+=_cop(11);
           else str+=_cop(COP%10);
           return str.c_str();
    }