小写数字转中文大写或大写金额的C#完整方案

原创 2004年08月17日 09:40:00

本程序用于将小写数字转换为一般中文大写或中文大写金额, 提供以下功能:
1. 允许任意整数或小数, 一般中文大写转换范围在(-10,000,000,000,000,000 ~ 10,000,000,000,000,000)之间, 中文大写金额转换范围在(0,? ~ 10,000,000,000,000,000)之间. 能转换所有系统接纳的输入数字, 如"0", "0.", ".0", "-.0", ".0-", "+114", "20.+"等.
2. 能识别并处理任何错误输入.
3. 算法稳定, 速度较快, 中文大写比较符合语言习惯

using System;
using System.Text;

namespace DigitToChnText
{
 ///
 /// 本程序用于将小写数字转换为
 /// 1. 一般中文大写数字
 /// 2. 人民币大写数字
 /// 算法设计:黄晶
 /// 程序制作:黄晶
 /// 时间:2004年8月12日
 ///
 class DigitToChnText
 {
  private readonly char[] chnGenText;
  private readonly char[] chnGenDigit;

  private readonly char[] chnRMBText;
  private readonly char[] chnRMBDigit;
  private readonly char[] chnRMBUnit;

  //
  // 构造函数
  //
  public DigitToChnText()
  {
   // 一般大写中文数字组
   chnGenText = new char[]{'零', '一', '二', '三', '四', '五', '六', '七', '八', '九'};
   chnGenDigit = new char[]{'十', '百', '千', '万', '亿'};

   // 人民币专用数字组
   chnRMBText = new char[]{'零', '壹', '贰', '叁', '肆', '伍', '陆', '染', '捌', '玖'};
   chnRMBDigit = new char[]{'拾', '佰', '仟', '萬', '億'};
   chnRMBUnit = new char[]{'角', '分'};
  }

  //
  // 主转换函数
  // 参数
  // string strDigit - 待转换数字字符串
  // bool  bToRMB  - 是否转换成人民币
  // 返回
  // string    - 转换成的大写字符串
  //
  public string Convert( string strDigit, bool bToRMB )
  {
   // 检查输入数字有效性
   CheckDigit(ref strDigit, bToRMB);

   // 定义结果字符串
   StringBuilder strResult = new StringBuilder();

   // 提取符号部分
   ExtractSign( ref strResult, ref strDigit, bToRMB );

   // 提取并转换整数和小数部分
   ConvertNumber( ref strResult, ref strDigit, bToRMB );

   return strResult.ToString();
  }

  //
  // 转换数字
  //
  protected void ConvertNumber( ref StringBuilder strResult, ref string strDigit, bool bToRMB )
  {
   int indexOfPoint;
   if( -1 == ( indexOfPoint = strDigit.IndexOf('.') ) ) // 如果没有小数部分
   {
    strResult.Append( ConvertIntegral( strDigit, bToRMB ) );

    if( bToRMB)  // 如果转换成人民币
    {
     strResult.Append( "圆整");
    }
   }
   else // 有小数部分
   {
    // 先转换整数部分
    if( 0 == indexOfPoint ) // 如果“.”是第一个字符
    {
     if( !bToRMB)  // 如果转换成一般中文大写
     {
      strResult.Append( '零' );
     }
    }
    else // 如果“.”不是第一个字符
    {
     strResult.Append( ConvertIntegral( strDigit.Substring( 0, indexOfPoint ), bToRMB ) );
    }

    // 再转换小数部分
    if( strDigit.Length - 1 != indexOfPoint ) // 如果“.”不是最后一个字符
    {
     if( bToRMB ) // 如果转换成人民币
     {
      if( 0 != indexOfPoint ) // 如果“.”不是第一个字符
      {
       if( 1 == strResult.Length && "零" == strResult.ToString() ) // 如果整数部分只是'0'
       {
        strResult.Remove(0, 1);  // 去掉“零”
       }
       else
       {
        strResult.Append( '圆' );
       }
      }
     }
     else
     {
      strResult.Append( '点' );
     }

     string strTmp = ConvertFractional( strDigit.Substring( indexOfPoint + 1 ), bToRMB );

     if( 0 != strTmp.Length ) // 小数部分有返回值
     {
      if( bToRMB && // 如果转换为人民币
       0 == strResult.Length && // 且没有整数部分
       "零" == strTmp.Substring( 0, 1 ) ) // 且返回字串的第一个字符是“零”
      {
       strResult.Append( strTmp.Substring( 1 ) );
      }
      else
      {
       strResult.Append( strTmp );
      }
     }

     if( bToRMB )
     {
      if( 0 == strResult.Length) // 如果结果字符串什么也没有
      {
       strResult.Append( "零圆整" );
      }
       // 如果结果字符串最后以"圆"结尾
      else if( "圆" == strResult.ToString().Substring( strResult.Length - 1, 1 ) )
      {
       strResult.Append( '整' );
      }
     }
    }
    else if( bToRMB ) // 如果"."是最后一个字符,且转换成人民币
    {
     strResult.Append( "圆整");
    }
   }
  }
  //
  // 检查输入数字有效性
  //
  private void CheckDigit( ref string strDigit, bool bToRMB )
  {
   decimal dec;
   try
   {
    dec = decimal.Parse( strDigit );
   }
   catch( FormatException )
   {
    throw new Exception("输入数字的格式不正确。");
   }
   catch( Exception e )
   {
    throw e;
   }

   if( bToRMB ) // 如果转换成人民币
   {
    if( dec >= 10000000000000000m)
    {
     throw new Exception( "输入数字太大,超出范围。" );
    }
    else if( dec < 0 )
    {
     throw new Exception( "不允许人民币为负值。");
    }
   }
   else   // 如果转换成中文大写
   {
    if( dec <= -10000000000000000m || dec >= 10000000000000000m )
    {
     throw new Exception( "输入数字太大或太小,超出范围。" );
    }
   }
  }

  //
  // 提取输入字符串的符号
  //
  protected void ExtractSign( ref StringBuilder strResult, ref string strDigit, bool bToRMB )
  {
   // '+'在最前
   if( "+" == strDigit.Substring( 0, 1 ) )
   {
    strDigit = strDigit.Substring( 1 );
   }
   // '-'在最前
   else if( "-" == strDigit.Substring( 0, 1 ) )
   {
    if( !bToRMB )
    {
     strResult.Append( '负' );
    }
    strDigit = strDigit.Substring( 1 );
   }
   // '+'在最后
   else if( "+" == strDigit.Substring( strDigit.Length - 1, 1 ) )
   {
    strDigit = strDigit.Substring( 0, strDigit.Length - 1 );
   }
   // '-'在最后
   else if( "-" == strDigit.Substring( strDigit.Length - 1, 1 ) )
   {
    if( !bToRMB )
    {
     strResult.Append( '负' );
    }
    strDigit = strDigit.Substring( 0, strDigit.Length - 1 );
   }
  }

  //
  // 转换整数部分
  //
  protected string ConvertIntegral( string strIntegral, bool bToRMB)
  {
   // 去掉数字前面所有的'0'
   // 并把数字分割到字符数组中
   char[] integral = ( ( long.Parse( strIntegral ) ).ToString() ).ToCharArray();

   // 定义结果字符串
   StringBuilder strInt = new StringBuilder();
   
   int digit;
   digit = integral.Length - 1;

   // 使用正确的引用
   char[] chnText = bToRMB ? chnRMBText : chnGenText;
   char[] chnDigit = bToRMB ? chnRMBDigit : chnGenDigit;
   
   // 变成中文数字并添加中文数位
   // 处理最高位到十位的所有数字
   int i;
   for( i = 0; i < integral.Length - 1; i++ )
   {
    // 添加数字
    strInt.Append( chnText[ integral[i] - '0'] );

    // 添加数位
    if( 0 == digit % 4 )     // '万' 或 '亿'
    {
     if( 4 == digit || 12 == digit )
     {
      strInt.Append( chnDigit[3] ); // '万'
     }
     else if( 8 == digit )
     {
      strInt.Append( chnDigit[4] ); // '亿'
     }
    }
    else         // '十','百'或'千'
    {
     strInt.Append( chnDigit[digit % 4 - 1] );
    }

    digit--;
   }

   // 如果个位数不是'0'
   // 或者只有一位数
   // 则添加相应的中文数字
   if( '0' != integral[ integral.Length - 1 ] || 1 == integral.Length )
   {
    strInt.Append( chnText[ integral[ i ] - '0' ] );
   }

 
   // 遍历整个字符串
   i = 0;
   string strTemp;  // 临时存储字符串
   int  j;    // 查找“零x”结构时用
   bool bDoSomething; // 找到“零万”或“零亿”时为真

   while( i < strInt.Length)
   {
    j = i;
   
    bDoSomething = false;

    // 查找所有相连的“零x”结构
    while( j < strInt.Length - 1 && "零" == strInt.ToString().Substring( j, 1 ) )
    {
      strTemp = strInt.ToString().Substring( j + 1, 1 );
    
     // 如果是“零万”或者“零亿”则停止查找
     if( chnDigit[ 3 ].ToString() /* 万或萬 */ == strTemp ||
      chnDigit[ 4 ].ToString() /* 亿或億 */ == strTemp )
     {
      bDoSomething = true;
      break;
     }

     j += 2;
    }

    if( j != i) // 如果找到非“零万”或者“零亿”的“零x”结构,则全部删除
    {
     strInt = strInt.Remove( i, j - i);

     // 除了在最尾处,或后面不是"零万"或"零亿"的情况下,
     // 其他处均补入一个“零”
     if(  i <= strInt.Length - 1 && !bDoSomething )
     {
      strInt = strInt.Insert( i, '零' );
      i++;
     }
    }
   
    if( bDoSomething ) // 如果找到"零万"或"零亿"结构
    {
     strInt = strInt.Remove( i, 1 ); // 去掉'零'
     i++;
     continue;
    }

    // 指针每次可移动2位
    i += 2;
   }

   // 遇到“亿万”变成“亿零”或"亿"
   strTemp = chnDigit[ 4 ].ToString() + chnDigit[ 3 ].ToString(); // 定义字符串“亿万”或“億萬”
   int index = strInt.ToString().IndexOf( strTemp );
   if( -1 != index )
   {
    if( strInt.Length - 2 != index &&  // 如果"亿万"不在末尾
     ( index + 2 < strInt.Length
      && "零" != strInt.ToString().Substring( index + 2, 1) ) ) // 并且其后没有"零"
    {
     strInt = strInt.Replace( strTemp, chnDigit[ 4 ].ToString(), index, 2 ); // 变“亿万”为“亿零”
     strInt = strInt.Insert( index + 1, "零" );
    }
    else  // 如果“亿万”在末尾或是其后已经有“零”
    {
     strInt = strInt.Replace( strTemp, chnDigit[ 4 ].ToString(), index, 2); // 变“亿万”为“亿”
    }
   }

   if( !bToRMB) // 如果转换为一般中文大写
   {
    // 开头为“一十”改为“十”
    if( strInt.Length > 1 && "一十" == strInt.ToString().Substring( 0, 2 ) )
    {
     strInt = strInt.Remove( 0, 1 );
    }
   }

   return strInt.ToString();
  }

  //
  // 转换小数部分
  //
  protected string ConvertFractional( string strFractional, bool bToRMB )
  {
   char[] fractional = strFractional.ToCharArray();

   StringBuilder strFrac = new StringBuilder();

   // 变成中文数字
   int i;
   if( bToRMB ) // 如果转换为人民币
   {
    for( i = 0; i < Math.Min( 2, fractional.Length ); i++)
    {
     strFrac.Append( chnRMBText[ fractional[ i ] - '0' ] );
     strFrac.Append( chnRMBUnit[ i ] );
    }

    // 如果最后两位是“零分”则删除
    if( "零分" == strFrac.ToString().Substring( strFrac.Length - 2, 2 ) )
    {
     strFrac.Remove( strFrac.Length - 2, 2 );
    }

    // 如果以“零角”开头
    if( "零角" == strFrac.ToString().Substring( 0, 2 ) )
    {
     // 如果只剩下“零角”
     if( 2 == strFrac.Length )
     {
      strFrac.Remove( 0, 2 );
     }
     else // 如果还有“x分”,则删除“角”
     {
      strFrac.Remove( 1, 1 );
     }
    }
   }
   else // 如果转换为一般中文大写
   {
    for( i = 0; i < fractional.Length; i++ )
    {
     strFrac.Append( chnGenText[ fractional[ i ] - '0' ] );
    }
   }

   return strFrac.ToString();
  }

  ///
  /// 应用程序主函数入口点
  ///
  [STAThread]
  static void Main(string[] args)
  {
   DigitToChnText obj = new DigitToChnText();

   string str = " ";
   while( "" != str )
   {
    Console.Write( "请输入小写数字: " );
    if( "" == ( str = Console.ReadLine() ) )
     break;
   
    try
    {
     Console.WriteLine( "中文大写数字为: {0}", obj.Convert( str, false ) );
    }
    catch( Exception e )
    {
     Console.WriteLine( "转换大写数字时出错: {0}", e.Message );
    }

    try
    {
     Console.WriteLine( "人民币大写为:   {0}/n", obj.Convert( str, true ) );
    }
    catch( Exception e )
    {
     Console.WriteLine( "转换人民币时出错:   {0}", e.Message );
    }

    Console.WriteLine();

   }   
  }
 }
}

C#人民币金额大写转换

人民币金额大小写转换,三行代码 //完善了一下查询到的方法,支持小数,保留2位小数 完善了一下查询到的方法,支持小数,保留2位小数 public string NumGetStr(double Nu...
  • CommandBaby
  • CommandBaby
  • 2015年11月28日 14:00
  • 2553

js 数字金额大小写转换成中文大写

function Arabia_to_Chinese(Num) { for(i=Num.length-1;i>=0;i--) { Num = Num.replace(",","")//替换to...
  • lychao89
  • lychao89
  • 2016年08月12日 10:02
  • 2833

jquery金额小写转大写

/** * 数字转中文 * @param dValue * @returns */ function chineseNumber(dValue) { var maxDec = 2...
  • baidu_28678737
  • baidu_28678737
  • 2015年07月03日 14:52
  • 1952

JAVA科学计数法,金额数字,转换为中文大写字

java操作金额
  • wangyonglin1123
  • wangyonglin1123
  • 2016年04月28日 13:46
  • 1790

Java将小写金额转换成大写

public class Test { private static final String UNIT = "万千佰拾亿千佰拾万千佰拾元角分"; private static final St...
  • leayefang
  • leayefang
  • 2016年11月09日 13:19
  • 1217

SQL人民币小写金额转大写

--1、人民币小写金额转大写(第一版) ==================================================================== -- Title:...
  • tlammon
  • tlammon
  • 2016年04月05日 22:03
  • 1468

jquery、js 金额小写转成大写

jquery、js 金额小写转成大写,本代码完成了基本的转换,并不是最完整的,可根据需求进行修改,比如是否可以有小数点,(金额小数点也就两位,精确到分)...
  • u012402177
  • u012402177
  • 2016年07月29日 11:43
  • 1213

将数字转为中文金额的大写方式(C++版)

/**   * 程序目的:   *   从命令行接收一个数,并将其转化为中文金额的大写方式(C++版)   * 例如 123.45 --> 壹佰贰拾叁元肆角伍分   * @author Lov...
  • u010944926
  • u010944926
  • 2014年03月08日 15:57
  • 3187

C#实现阿拉伯数字到大写中文的转换

原文地址:http://www.jb51.net/article/8061.htm /// /// 金额转为大写金额 /// public class MoneyCon...
  • cxcalm
  • cxcalm
  • 2015年08月18日 09:17
  • 3084

java实现金钱数字转大写

private static final char [] ChineseNum ={'零','壹','贰','叁','肆','伍','陆','柒','捌','玖'}; private static ...
  • qiumin333
  • qiumin333
  • 2016年11月25日 19:55
  • 2845
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:小写数字转中文大写或大写金额的C#完整方案
举报原因:
原因补充:

(最多只允许输入30个字)