资源描述
using System;
using System.Text;
namespace DigitToChnText
{
///本程序用于将小写数字转换为中文大写, 提供以下功能:
//2. 能识别并处理任何错误输入
//3. 算法稳定, 速度较快, 中文大写比较符合语言习惯
/// 本程序用于将小写数字变成大写中文数字
class DigitToChnText
{
private readonly char[] chnText;
private readonly char[] chnDigit;
public DigitToChnText()
{
chnText = new char[]{'零', '一', '二', '三', '四', '五', '六', '七', '八', '九'};
chnDigit = new char[]{'十', '百', '千', '万', '亿'};
}
public string Convert( string strDigit )
{
// 检查输入数字
decimal dec;
try
{
dec = decimal.Parse( strDigit );
}
catch( FormatException )
{
throw new Exception("输入数字的格式不正确。");
}
catch( Exception e )
{
throw e;
}
if( dec <= -10000000000000000m || dec >= 10000000000000000m )
{
throw new Exception( "输入数字太大或太小,超出范围。" );
}
StringBuilder strResult = new StringBuilder();
// 提取符号部分
// '+'在最前
if( "+" == strDigit.Substring( 0, 1 ) )
{
strDigit = strDigit.Substring( 1 );
}
// '-'在最前
else if( "-" == strDigit.Substring( 0, 1 ) )
{
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 ) )
{
strResult.Append( '负' );
strDigit = strDigit.Substring( 0, strDigit.Length - 1 );
}
// 提取整数和小数部分
int indexOfPoint;
if( -1 == ( indexOfPoint = strDigit.IndexOf('.') ) ) // 如果没有小数部分
{
strResult.Append( ConvertIntegral( strDigit ) );
}
else // 有小数部分
{
// 先转换整数部分
if( 0 == indexOfPoint ) // 如果“.”是第一个字符
{
strResult.Append( '零' );
}
else
{
strResult.Append( ConvertIntegral( strDigit.Substring( 0, indexOfPoint ) ) );
}
// 再转换小数部分
if( strDigit.Length - 1 != indexOfPoint ) // 如果“.”不是最后一个字符
{
strResult.Append( '点');
strResult.Append( ConvertFractional( strDigit.Substring( indexOfPoint + 1 ) ) );
}
}
return strResult.ToString();
}
// 转换整数部分
protected string ConvertIntegral(string strIntegral)
{
// 去掉数字前面所有的'0'
// 并把数字分割到字符数组中
char[] integral = ( ( long.Parse( strIntegral ) ).ToString() ).ToCharArray();
// 变成中文数字并添加中文数位
StringBuilder strInt = new StringBuilder();
int i;
int digit;
digit = integral.Length - 1;
// 处理最高位到十位的所有数字
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'
// 或者个位数为‘0’但只有一位数
// 则添加相应的中文数字
if( '0' != integral[ integral.Length - 1 ] || 1 == integral.Length )
{
strInt.Append( chnText[ integral[ i ] - '0' ] );
}
// 遍历整个字符串
i = 0;
while( i < strInt.Length)
{
int j = i;
bool bDoSomething = false;
// 查找所有相连的“零X”结构
while( j < strInt.Length - 1 && "零" == strInt.ToString().Substring( j, 1 ) )
{
string strTemp = strInt.ToString().Substring( j + 1, 1 );
// 如果是“零万”或者“零亿”则停止查找
if( "万" == strTemp || "亿" == 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;
}
// 遇到“亿万”变成“亿零”或"亿"
int index = strInt.ToString().IndexOf( "亿万" );
if( -1 != index )
{
if( strInt.Length - 2 != index && // 如果"亿万"不在最后
( index + 2 < strInt.Length && "零" != strInt.ToString().Substring( index + 2, 1) ) ) // 并且其后没有"零"
strInt = strInt.Replace( "亿万", "亿零", index, 2 );
else
strInt = strInt.Replace( "亿万", "亿", index, 2);
}
// 开头为“一十”改为“十”
if( strInt.Length > 1 && "一十" == strInt.ToString().Substring( 0, 2 ) )
{
strInt = strInt.Remove( 0, 1 );
}
return strInt.ToString();
}
// 转换小数部分
protected string ConvertFractional( string strFractional )
{
char[] fractional = strFractional.ToCharArray();
StringBuilder strFrac = new StringBuilder();
// 变成中文数字
int i;
for( i = 0; i < fractional.Length; i++ )
{
strFrac.Append( chnText[ fractional[ i ] - '0' ] );
}
return strFrac.ToString();
}
///
/// The main entry point for the application.
///
[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}\n", obj.Convert( str ) );
}
catch( Exception e )
{
Console.WriteLine( "错误: {0}\n", e.Message );
continue;
}
}
}
}
}
本文来自CSDN博客,转载请标明出处:
方法二:
例如:(new Money(200)).ToString() == "贰佰元 "
namespace Skyiv.Util
{
using System.Text;
class Test
{
static void Main()
{
for (;;)
{
System.Console.Write( "金额: ");
string s = System.Console.ReadLine();
decimal m;
try { m = decimal.Parse(s); }
catch { break; }
System.Console.WriteLine( "大写: " + new Money(m));
}
}
}
// 该类重载的 ToString() 方法返回的是大写金额字符串
class Money
{
public string Yuan = "元 "; // “元”,可以改为“圆”、“卢布”之类
public string Jiao = "角 "; // “角”,可以改为“拾”
public string Fen = "分 "; // “分”,可以改为“美分”之类
static string Digit = "零壹贰叁肆伍陆柒捌玖 "; // 大写数字
bool isAllZero = true; // 片段内是否全零
bool isPreZero = true; // 低一位数字是否是零
bool Overflow = false; // 溢出标志
long money100; // 金额*100,即以“分”为单位的金额
long value; // money100的绝对值
StringBuilder sb = new StringBuilder(); // 大写金额字符串,逆序
// 只读属性: "零元 "
public string ZeroString
{
get { return Digit[0] + Yuan; }
}
// 构造函数
public Money(decimal money)
{
try { money100 = (long)(money * 100m); }
catch { Overflow = true; }
if (money100 == long.MinValue) Overflow = true;
}
// 重载 ToString() 方法,返回大写金额字符串
public override string ToString()
{
if (Overflow) return "金额超出范围 ";
if (money100 == 0) return ZeroString;
string [] Unit = { Yuan, "万 ", "亿 ", "万 ", "亿亿 " };
value = System.Math.Abs(money100);
ParseSection(true);
for (int i = 0; i < Unit.Length && value > 0; i++)
{
if (isPreZero && !isAllZero) sb.Append(Digit[0]);
if (i == 4 && sb.ToString().EndsWith(Unit[2]))
sb.Remove(sb.Length - Unit[2].Length, Unit[2].Length);
sb.Append(Unit[i]);
ParseSection(false);
if ((i % 2) == 1 && isAllZero)
sb.Remove(sb.Length - Unit[i].Length, Unit[i].Length);
}
if (money100 < 0) sb.Append( "负 ");
return Reverse();
}
// 解析“片段”: “角分(2位)”或“万以内的一段(4位)”
void ParseSection(bool isJiaoFen)
{
string [] Unit = isJiaoFen ?
new string [] { Fen, Jiao } :
new string [] { " ", "拾 ", "佰 ", "仟 " };
isAllZero = true;
for (int i = 0; i < Unit.Length && value > 0; i++)
{
int d = (int)(value % 10);
if (d != 0)
{
if (isPreZero && !isAllZero) sb.Append(Digit[0]);
sb.AppendFormat( "{0}{1} ", Unit[i], Digit[d]);
isAllZero = false;
}
isPreZero = (d == 0);
value /= 10;
}
}
// 反转字符串
string Reverse()
{
StringBuilder sbReversed = new StringBuilder();
for (int i = sb.Length - 1; i > = 0; i--)
sbReversed.Append(sb[i]);
return sbReversed.ToString();
}
}
}
展开阅读全文