这是以前做的一个打印的小东西,需要用到金额转换。
在网上搜到做金额转换的很多都是VB或者JavaScript的代码,基本上都是利用的字符串替换。感觉用stack先push进去再pop出来好像更容易理解。
转换前:
转换后:
测试程序:
// MoneyConverterTst.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "MoneyConverter.h"
#include <iostream>
int main(int argc, char* argv[])
{
MoneyConverter converter;
tstring money=_T("123400123.19");
cout<<converter.DigitalStr2Chinese(money)<<endl;
return 0;
}
测试程序输出结果:
MoneyConverter的源代码:
// MoneyConverter.h: interface for the MoneyConverter class.
//
#if !defined(AFX_MONEYCONVERTER_H__AA9A99D8_5205_4BF1_89DE_5E9718A39887__INCLUDED_)
#define AFX_MONEYCONVERTER_H__AA9A99D8_5205_4BF1_89DE_5E9718A39887__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <string>
#include <stack>
#include <tchar.h>
typedef std::basic_string<TCHAR> tstring;
using namespace std;
class MoneyConverter
{
public:
MoneyConverter();
virtual ~MoneyConverter();
tstring DigitalStr2Chinese(tstring& str);
protected:
//是否合法数字字符串
bool IsDigitString(tstring& str);
//转换整数部分
tstring ConvertIntergerPart(tstring& str);
//转换小数部分
tstring ConvertFractionalPart(tstring& str);
private:
TCHAR* unit1[4];
TCHAR* unit2[3];
TCHAR* unit3[2];
TCHAR* digital[10];
};
#endif // !defined(AFX_MONEYCONVERTER_H__AA9A99D8_5205_4BF1_89DE_5E9718A39887__INCLUDED_)
// MoneyConverter.cpp: implementation of the MoneyConverter class.
//
#include "stdafx.h"
#include "MoneyConverter.h"
// Construction/Destruction
MoneyConverter::MoneyConverter()
{
unit1[0]=_T("");unit1[1]=_T("拾");unit1[2]=_T("佰");unit1[3]=_T("仟");
unit2[0]=_T("");unit2[1]=_T("萬");unit2[2]=_T("亿");
unit3[0]=_T("角");unit3[1]=_T("分");
digital[0]=_T("零");digital[1]=_T("壹");digital[2]=_T("贰");digital[3]=_T("叁");
digital[4]=_T("肆");digital[5]=_T("伍");digital[6]=_T("陆");digital[7]=_T("柒");
digital[8]=_T("捌");digital[9]=_T("玖");
}
MoneyConverter::~MoneyConverter()
{
}
tstring MoneyConverter::DigitalStr2Chinese(tstring& str)
{
if(!IsDigitString(str))
return _T("not valid digital string!");
int pos=str.find_first_of('.');
tstring str1=str.substr(0,pos);
tstring str2;
if(pos > 0)
str2=str.substr(pos+1,str.rfind('.'));
return ConvertIntergerPart(str1)+ConvertFractionalPart(str2);
}
tstring MoneyConverter::ConvertIntergerPart(tstring& str)
{
std::stack<TCHAR*> s;
int index1, index2, pos;
index1 = index2 = pos = 0;
s.empty();
tstring::reverse_iterator it;//从低位开始
for(it=str.rbegin();it!=str.rend();it++)//入栈
{
if(index2>0 && index1==0)
s.push(unit2[index2]);
if(*it != '0')
s.push(unit1[index1]);
//个位上的零不写,连续的零只写一个
if(!(*it=='0' && (index1==0 || *(it-1)=='0' )))
s.push(digital[*it-'0']);
//
pos++;
index1=pos%4;//每四位一组
index2=(pos/4)%3;//
//
if(pos>8 && index2==0)//大于千万
index2++;
}
//
tstring result;
while(!s.empty())//出栈
{
tstring c=s.top();
if(!c.empty())
result.append(c);
s.pop();
}
result.append(_T("圆"));
return result;
}
tstring MoneyConverter::ConvertFractionalPart(tstring& str)
{
tstring sJiao,sFen,result;
if(str.length()==1)
sJiao=str.substr(0,1);
if(str.length() > 1)
sFen=str.substr(1,1);
if(sJiao==_T("0")) sJiao=_T("");
if(sFen==_T("0")) sFen=_T("");
if(sJiao.empty() && sFen.empty()){
result=_T("整");
}
else if(!sJiao.empty() && sFen.empty()){
result=tstring(digital[atoi(sJiao.c_str())])+_T("角");
}
else if(sJiao.empty() && !sFen.empty()){
result=tstring(_T("零"))+tstring(digital[atoi(sFen.c_str())])+_T("分");
}
else{
result=tstring(digital[atoi(sJiao.c_str())])+tstring(_T("角"))+
tstring(digital[atoi(sFen.c_str())])+_T("分");
}
return result;
}
bool MoneyConverter::IsDigitString(tstring& str)
{
if (str.size() == 0)
return false;
std::string::size_type index = 0;
bool sawdot = false;
if((str[0] == '-') || (str[0] == '+'))
index++;
for( ; index < str.size(); index++)
{
if (str[index] == '.')
{
if (sawdot)
return false;
else sawdot = true;
}
else if (!isdigit(str[index]))
return false;
}
return true;
}