zoukankan      html  css  js  c++  java
  • 成熟稳定的数字转换为汉字金额大写文字函数

    在开发Grid++Report报表工具的过程中,需要一个将数字转换为汉字金额大写文字的函数。在网上也搜索到了一些朋友奉献的作品,但仔细查阅之后都有一些不足。最后没有办法,只好综合各方的思路再次做了重新发明轮子的事。整个函数还是比较复杂,但有Grid++Report庞大用户群的考验,可以保证这个转换汉字金额大写的函数是成熟稳定高效的。在此奉献出来,希望能帮到需要的朋友,免除不必要的做重新发明轮子的苦差。

    代码是用VC++写的,如下:


    #include "stdafx.h"
    #include <string>
    #include <atlstr.h>

    using namespace std;
    using namespace ATL;

    const char Const_Str_ZeroYuan[] = "零元整";
    const char Const_Str_BigAmtNumber[] = "零壹贰叁肆伍陆柒捌玖";
    const char Const_Str_HZNegative[] = "负";
    const CString strUnit = "元拾佰仟万拾佰仟亿拾佰仟";
    const CString strNumber = Const_Str_BigAmtNumber;
    const CString strOtherUnit = "整角分";

    string ToBigMoney(double dMoney)
    {
     const double ZeroLowRange = -0.005; //-0.004449;
     const double ZeroHighRange = 0.005; //0.004449;
     if (ZeroLowRange < dMoney && dMoney < ZeroHighRange)
      return Const_Str_ZeroYuan; //"零元整";

     bool Negative = FALSE;
     if (dMoney <= ZeroLowRange)
     {
      Negative = TRUE;
      dMoney = -dMoney;
     }

     //这里没有对超出部份作异常,使用者要注意(现实中不会出现如此巨大的金额数)
         CString strMoney;
         strMoney.Format ("%.2f" , dMoney);

         //将数字分整数部份与小数部份处理
         int nPos = strMoney.Find (".");
         int nLength = strMoney.GetLength ();
         if(nPos < 0)
             nPos = nLength;

         CString strReturnValue;
         int nCount = 0;
         bool bZero = false;
         bool bNeedLevel = false;    //对段的识别,用于是否需要出现段名,如亿,万等

         //对整数部份进行反相识别处理
         for(int i = nPos - 1;i >= 0;i --)
         {
             char ch = strMoney.GetAt (i);

      if(nCount % 4 == 0 && nCount > 0)
            {
                   //如果处理的数字为第四位(万),或第八位(亿)等,则要求置段
                  bNeedLevel = true;
            }

            if(ch == '0')
            {
       //只对拾佰仟位的0进行识别,主要考虑到拾的特殊性,即如10读壹拾,不会读壹拾零
       //if(nCount % 4 != 0)
       //   bZero = true;
       bZero = true; //去掉%4判断, 让 102000 读做:壹拾万零贰仟元整。9,050,155,001-〉玖拾亿零伍仟零壹拾伍万伍仟零壹元整
            }
            else
            {
                  CString strTemp(strReturnValue);
                  strReturnValue = strNumber.Mid ((ch - 0x30) * 2 , 2);

                  if(nCount > 0)
                  {
                      strReturnValue += strUnit.Mid (nCount * 2 , 2);
                      if(nCount % 4 != 0 && bNeedLevel)
                      {
                             //这里判断是否需要读段名,如万,亿等
                           strReturnValue += strUnit.Mid (int(nCount / 4) * 8 , 2);
                      }
                      bNeedLevel = false;
                  }

                  if(bZero)
                  {
                       //只有比当前处理的位要低中有数字才补零
                       if( !strTemp.IsEmpty () )
                           strReturnValue += strNumber.Left (2);
                       bZero = false;
                  }

                  strReturnValue += strTemp;
             }

             nCount ++;
         }

      //如果没有整数部分,则不用加元
      if ( !strReturnValue.IsEmpty() )
      strReturnValue += strUnit.Left (2);


         //下面实现对小数点后面的处理, 先判断是否为全零,则不需要继续读
         bool bAllZero = true;
         if(nPos < nLength)
         {
             if(nLength > 2)
                  nLength = 2;
             for(int i = 0;i < nLength;i ++)
                  if(strMoney.GetAt (nPos + i + 1) != '0')
                       bAllZero = false;
         }

         if(bAllZero)
         {
             strReturnValue += strOtherUnit.Left (2);
         }
         else
         {
            //对角的处理,如果没有整数部分,则不用加上零角的零
            char ch = strMoney.GetAt (nPos + 1);
            if(ch != '0' || !strReturnValue.IsEmpty())
       strReturnValue += strNumber.Mid ((ch - 0x30) * 2 , 2);
      if(ch != '0')
       strReturnValue += strOtherUnit.Mid (1 * 2 , 2);
     
            //对分的处理,如果没有分,角后加‘整’
            ch = strMoney.GetAt (nPos + 1 + 1);
      if(ch != '0')
      {
       strReturnValue += strNumber.Mid ((ch - 0x30) * 2 , 2);
       strReturnValue += strOtherUnit.Mid (2 * 2 , 2);
      }
      else
      {
       strReturnValue += strOtherUnit.Left (2);
      }
         }

     if (Negative)
      strReturnValue = Const_Str_HZNegative + strReturnValue;

     return string(strReturnValue);
    }


    锐浪报表Grid++Report源自2003年,经过多年持续不断发展,是拥有最多软件开发者的报表工具。易学易用,功能丰富,成熟稳定,支持各种编程环境下的报表开发。

  • 相关阅读:
    Python 面向对象4-特殊成员
    Python 面向对象3-成员修饰符
    Python 面向对象2
    Python 面向对象
    Python hashlib模块
    使用Access-Control-Allow-Origin解决跨域
    倒计时
    移动端之touch事件--手指的滑动事件
    HTML5获取地理经纬度并通过百度接口得到实时位置
    h5直播
  • 原文地址:https://www.cnblogs.com/report/p/1241597.html
Copyright © 2011-2022 走看看