henry10423 发表于 2013-2-27 00:17:55

字串问题 求解

本帖最后由 henry10423 于 2013-2-27 00:28 编辑

我写了个程式,将阿拉伯数字转成中文数字...
只是有Bug...
举例:
输入1000 会输出为 "一千零百零十零"
输入120 会输出为"一百二十零"
输入130000 会输出为"一十三万零千零百零十零"
#include <String.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

$Form1 = GUICreate("Form1", 350, 123, 546, 267)
$InputNum = GUICtrlCreateInput("", 48, 24, 169, 21)
$showabel1 = GUICtrlCreateLabel("", 170, 72, 148, 33)
$btn2 = GUICtrlCreateButton("转换", 56, 72, 100, 33)
Dim $Number =
Dim $chNum = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"]
Dim $getFinalNum
GUISetState(@SW_SHOW)

While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit

                Case $btn2
                        Local $read = GUICtrlRead($InputNum)
                        Local $checkLen = StringLen($read)
                        Local $chNum, $show, $fullNum

                        For $i = 1 To $checkLen Step + 1
                                $checkNum = StringMid($read, $i, 1)
                                For $s = 0 To UBound($Number) - 1
                                        If $checkNum == $Number[$s] Then
                                                $getNum = $chNum[$s]
                                        EndIf
                                Next
                                $show &= $getNum
                        Next

                        $getFinalNum = $show
                        $getFinalNum = _StringInsert($show, "十", 1)
                        $getFinalNum = _StringInsert(_StringInsert($show, "百", 1), "十", 3)
                        $getFinalNum = _StringInsert(_StringInsert(_StringInsert($show, "千", 1), "百", 3), "十", 5)
                        $getFinalNum = _StringInsert(_StringInsert(_StringInsert(_StringInsert($show, "万", 1), "千", 3), "百", 5), "十", 7)
                        $getFinalNum = _StringInsert(_StringInsert(_StringInsert(_StringInsert(_StringInsert($show, "十", 1), "万", 3), "千", 5), "百", 7), "十", 9)
                        $getFinalNum = _StringInsert(_StringInsert(_StringInsert(_StringInsert(_StringInsert(_StringInsert($show, "百", 1), "十", 3), "万", 5), "千", 7), "百", 9), "十", 11)
                        $getFinalNum = _StringInsert(_StringInsert(_StringInsert(_StringInsert(_StringInsert(_StringInsert(_StringInsert($show, "千", 1), "百", 3), "十", 5), "万", 7), "千", 9), "百", 11), "十", 13)

                        For $i = 0 To UBound($getFinalNum) - 1
                                If $checkLen == ($i + 1) Then
                                        $fullNum = $getFinalNum[$i]
                                EndIf
                        Next

                        GUICtrlSetData($showabel1, $fullNum)

        EndSwitch
WEnd
求各位大侠的有效帮助
感谢了!

水木子 发表于 2013-2-27 08:54:21

http://www.autoitx.com/forum.php?mod=viewthread&tid=17196&highlight=

henry10423 发表于 2013-2-27 09:23:23


水木子 发表于 2013-2-27 08:54 http://www.autoitx.com/images/common/back.gif


太棒了,
完美解决,
感谢热情帮助!!

happytc 发表于 2013-2-27 14:38:04

回复 1# henry10423


    我也把以前给别人会计用的转换大写人民币,给你参考。
以前是用c写的,我转成au3了,添加了无数的'$',累死了


$iNum = InputBox("Arabic Number", "Input Arabic Number: ", "12,005,678.991")
$sCnNum = convertCurrency($iNum)
If $sCnNum Then MsgBox(0, "Result", $sCnNum)

Func convertCurrency($currencyDigits)
        ;// Constants:
        Local Const $MAXIMUM_NUMBER = 99999999999.99;
        ;// Predefine the radix characters and currency symbols for output:
        Local Const $CN_ZERO = "零";
        Local Const $CN_ONE = "壹";
        Local Const $CN_TWO = "贰";
        Local Const $CN_THREE = "叁";
        Local Const $CN_FOUR = "肆";
        Local Const $CN_FIVE = "伍";
        Local Const $CN_SIX = "陆";
        Local Const $CN_SEVEN = "柒";
        Local Const $CN_EIGHT = "捌";
        Local Const $CN_NINE = "玖";
        Local Const $CN_TEN = "拾";
        Local Const $CN_HUNDRED = "佰";
        Local Const $CN_THOUSAND = "仟";
        Local Const $CN_TEN_THOUSAND = "万";
        Local Const $CN_HUNDRED_MILLION = "亿";
        Local Const $CN_SYMBOL = "人民币:";
        Local Const $CN_DOLLAR = "圆";
        Local Const $CN_TEN_CENT = "角";
        Local Const $CN_CENT = "分";
        Local Const $CN_INTEGER = "整";   
        ;// Variables:
        Local $integral; // Represent integral part of digit number.
        Local $decimal; // Represent decimal part of digit number.
        Local $outputCharacters; // The output result.
        Local $parts;
        Local $digits, $radices, $bigRadices, $decimals;
        Local $zeroCount;
        Local $i, $p, $d;
        Local $quotient, $modulus;
        ;// Validate input string:
        $currencyDigits = String($currencyDigits);
        if ($currencyDigits == "") Then
                ConsoleWrite("Empty input!");
                return "";
        EndIf
        if StringRegExp($currencyDigits, '[^,.\d]') Then
                ConsoleWrite("Invalid characters in the input string!");
                return "";
        EndIf
        if Not StringRegExp($currencyDigits, '^((\d{1,3}(,\d{3})*(\.((\d{3},)*\d{1,3}))?)|(\d+(\.\d+)?))$') Then
                ConsoleWrite("Illegal format of digit number!");
                return "";
        EndIf
        ;// Normalize the format of input digits:
        $currencyDigits = StringRegExpReplace($currencyDigits, ',', ""); // Remove comma delimiters.
        $currencyDigits = StringRegExpReplace($currencyDigits, '^0+', ""); // Trim zeros at the beginning.
        ;// Assert the number is not greater than the maximum number.
        if Number($currencyDigits) > $MAXIMUM_NUMBER Then
                ConsoleWrite("Too large a number to convert!");
                return "";
        EndIf
        ;// Process the coversion from currency digits to characters:
        ;// Separate integral and decimal parts before processing coversion:
        $parts = StringSplit($currencyDigits, ".", 2);
        if UBound($parts) > 1 Then
               $integral = $parts;
               $decimal = $parts;
               ;// Cut down redundant decimal digits that are after the second.
               $decimal = StringMid($decimal, 1, 2);
        else
                $integral = $parts;
                $decimal = "";
        EndIf
        ;// Prepare the characters corresponding to the digits:
        Local $digits = [$CN_ZERO, $CN_ONE, $CN_TWO, $CN_THREE, $CN_FOUR, $CN_FIVE, $CN_SIX, $CN_SEVEN, $CN_EIGHT, $CN_NINE];
        Local $radices = ["", $CN_TEN, $CN_HUNDRED, $CN_THOUSAND];
        Local $bigRadices = ["", $CN_TEN_THOUSAND, $CN_HUNDRED_MILLION];
        Local $decimals = [$CN_TEN_CENT, $CN_CENT];
        ;// Start processing:
        $outputCharacters = "";
        ;// Process integral part if it is larger than zero:
        if Number($integral) > 0 Then
                $zeroCount = 0;
                for $i = 0 To StringLen($integral) - 1
                        $p = StringLen($integral) - $i - 1;
                        $d = StringMid($integral, $i + 1, 1);
                        $quotient = $p / 4;
                        $modulus = Mod($p, 4);
                        if $d == "0" Then
                                $zeroCount += 1;
                        else
                                if $zeroCount > 0 Then   
                                        $outputCharacters &= $digits;
                                EndIf
                                $zeroCount = 0;
                                $outputCharacters &= $digits & $radices[$modulus];
                        EndIf
                        if $modulus == 0 And $zeroCount < 4 Then
                                $outputCharacters &= $bigRadices[$quotient];
                        EndIf
                Next
                $outputCharacters &= $CN_DOLLAR;
        EndIf
        ;// Process decimal part if there is:
        if $decimal <> "" Then
                for $i = 0 To StringLen($decimal) - 1
                        $d = StringMid($decimal, $i + 1, 1);
                        if $d <> "0" Then
                                $outputCharacters &= $digits & $decimals[$i];
                        EndIf
                Next
        EndIf
        ;// Confirm and return the final output string:
        if $outputCharacters == "" Then
                $outputCharacters = $CN_ZERO & $CN_DOLLAR;
        EndIf
        if $decimal == "" Then
                $outputCharacters &= $CN_INTEGER;
        EndIf
        $outputCharacters = $CN_SYMBOL & $outputCharacters;
        return $outputCharacters;
EndFunc

afan 发表于 2013-2-27 14:44:45

本帖最后由 afan 于 2013-2-27 14:56 编辑

来个简单的
$Form1 = GUICreate('Form1', 350, 123, 546, 267)
$InputNum = GUICtrlCreateInput('12000000000000000', 48, 24, 140, 21,0x2000);$ES_NUMBER = 0x2000
GUICtrlSetLimit(-1, 17)
$showabel1 = GUICtrlCreateLabel('最大支持17位', 20, 72, 330, 30)
$btn2 = GUICtrlCreateButton('转换', 200, 24, 100, 22)
GUISetState()
While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case -3
                        Exit
                Case $btn2
                        $sRt = _Num2Cn(GUICtrlRead($InputNum))
                        GUICtrlSetData($showabel1, $sRt)
        EndSwitch
WEnd

Func _Num2Cn($Num)
        Local $aNum = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']
        Local $aCn = ['个', '十', '百', '千', '万', '十', '百', '千', '亿', '十', '百', '千', '兆', '十', '百', '千', '京']
        Local $iNLen = StringLen($Num), $sNum
        If $iNLen > 17 Then Return SetError(1, '', '超出最高17位数')
        For $i = 1 To $iNLen
                $sNum &= StringMid($Num, $i, 1) & $aCn[$iNLen - $i]
        Next
        $sNum = StringTrimRight($sNum, 1)
        $sNum = StringRegExpReplace(StringRegExpReplace($sNum, '0[千百十个]', '0'), '0000\D', '0')
        $sNum = StringRegExpReplace($sNum, '(?<=十)0+([百千万亿兆])|(?<=百)0+([千万亿兆])|(?<=千)0+([万亿兆])|(?<=万)0+([亿兆])', '\1\2\3\4')
        $sNum = StringRegExpReplace($sNum, '0[亿万千百十个]', '0')
        $sNum = StringRegExpReplace(StringRegExpReplace($sNum, '0+$', ''), '0+', '零')
        For $i = 0 To 9
                $sNum = StringRegExpReplace($sNum, $i, $aNum[$i])
        Next
        Return $sNum
EndFunc   ;==>_Num2Cn

henry10423 发表于 2013-2-27 18:13:40

来个简单的
afan 发表于 2013-2-27 14:44 http://www.autoitx.com/images/common/back.gif


    afan 哥 ,谢啦..果真不错! 厉害!

henry10423 发表于 2013-2-27 18:14:52

回复henry10423


    我也把以前给别人会计用的转换大写人民币,给你参考。
以前是用c写的,我转成 ...
happytc 发表于 2013-2-27 14:38 http://www.autoitx.com/images/common/back.gif


    这个有点复杂了,看来我要熟悉一下了...
都是高手,果然思维就是不凡..

netegg 发表于 2013-3-3 04:21:58

本帖最后由 netegg 于 2013-3-3 07:02 编辑

Local $num = 157800056690
global $aNum = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
Local $unit = ['', '万', '亿']
Local $i = 0
Global $retc = ''
While StringRight($num, 4)
        Switch StringLen(StringRight($num, 4))
                Case 4
                        $retc = convert(StringRight(StringRight($num, 4), 1), StringMid(StringRight($num, 4), 3, 1), StringMid(StringRight($num, 4), 2, 1), StringLeft(StringRight($num, 4), 1)) & $unit[$i] & $retc
                Case 3
                        $retc = convert(StringRight(StringRight($num, 3), 1), StringMid(StringRight($num, 3), 2, 1), StringLeft(StringRight($num, 3), 1)) & $unit[$i] & $retc
                Case 2
                        $retc = convert(StringRight(StringRight($num, 2), 1), StringLeft(StringRight($num, 2), 1)) & $unit[$i] & $retc
                Case 1
                        $retc = convert($num) & $unit[$i] & $retc
        EndSwitch
        $num = StringTrimRight($num, 4)
        $i += 1
WEnd
MsgBox(0, 0, $retc)
Func convert($s4='',$s3='',$s2='', $s1 = '')
        Local$ret = ''
        If $s1<>0 Then $ret &= $aNum[$s1] & '仟'
        If $s2<>0 Then $ret &= $aNum[$s2] & '佰'
        If $s3<>0 Then $ret &= $aNum[$s3] & '拾'
        If $s4<>0 then $ret &= $aNum[$s4]
        ConsoleWrite($ret & @cr)
        Return $ret
EndFunc   ;==>convert

afan 发表于 2013-3-3 10:39:56

回复 8# netegg


    貌似后面加个1就不对了 Local $num = 1578000566901

netegg 发表于 2013-3-3 10:56:38

本帖最后由 netegg 于 2013-3-3 11:38 编辑

回复 9# afan
单位超了,四个为一组,最多到千亿,后面的需要加大$unit的元素,图片只是演示下
这个问题不是很大,不过需要想想,原来曾经想过,要循环使用unit数组。逻辑需要设计设计
如果指的是百位和十位的零那好办,判断部分的子函数稍改下就行Func convert($s4 = 0, $s3 = 0, $s2 = 0, $s1 = 0)
        Local $ret = ''
        If Not StringInStr($s1, '0') Then $ret &= $aNum[$s1] & '仟'
        If Not StringInStr($s2, '0') Then $ret &= $aNum[$s2] & '佰'
        If Not StringInStr($s3, '0') Then $ret &= $aNum[$s3] & '拾'
        If Not StringInStr($s4, '0') Then
                If Not $i Then
                        $ret &= $aNum & $aNum[$s4]
                Else
                        $ret &= $aNum[$s4]
                EndIf
        EndIf
        ConsoleWrite($ret & @CR)
        Return $ret
EndFunc   ;==>convert
前面的$i用global声明

netegg 发表于 2013-3-3 14:18:02

本帖最后由 netegg 于 2013-3-3 15:28 编辑

整个简单些的
Local $num = 157760974098056690
Global $aNum = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
Local $unit = ['', '万', '亿', '兆', '京']
Local $i = 0
Global $retc = ''
If Not IsInt(StringLen($num) / 4) Then
        $format = '%0' & Ceiling(StringLen($num) / 4) * 4 & 's'
        $num = StringFormat($format, $num)
        MsgBox(0, 0, $num)
EndIf
While StringRight($num, 4)
        $retc = StringFormat('%s仟%s佰%s拾%s', $aNum, _
                        $aNum, $aNum, $aNum) & $unit[$i] & $retc
        $num = StringTrimRight($num, 4)
        $i += 1
WEnd
While 1
        $number = StringInStr($retc, '零')
        If Not $number Then ExitLoop
        ConsoleWrite(StringMid($retc, $number + 1, 1) & @CR)
        If StringInStr('万亿兆京', StringMid($retc, $number + 1, 1)) Then
                $last = StringTrimLeft($retc, $number)
        Else
                $last = StringTrimLeft($retc, $number + 1)
        EndIf
        $first = StringLeft($retc, $number - 1)
        If $number Then $retc = $first & $last
WEnd
MsgBox(0, 0, $retc)


henry10423 发表于 2013-3-3 14:45:21

回复 11# netegg


    猛!

afan 发表于 2013-3-3 15:25:02

整个简单些的
netegg 发表于 2013-3-3 14:18 http://www.autoitx.com/images/common/back.gif


    似乎都少了“零”界,比如“玖佰壹” 和 “玖佰零壹”相差10倍

netegg 发表于 2013-3-3 15:29:36

本帖最后由 netegg 于 2013-3-3 16:11 编辑

回复 13# afan
再试试,嗯,好像是,不过这个问题不大,判断处理下有没有,加下就行了
还有,忘了题目了,如果是纯数字的话需要处理,如果是金额的话好像不用

#include<array.au3>
Local $num = 1577609740980566901
Global $aNum = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
Local $unit = ['', '万', '亿', '兆', '京']
Local $i = 0
Global $retc = ''
If Not IsInt(StringLen($num) / 4) Then
        $format = '%0' & Ceiling(StringLen($num) / 4) * 4 & 's'
        $num = StringFormat($format, $num)
EndIf
While StringRight($num, 4)
        $retc = StringFormat('%s仟%s佰%s拾%s', $aNum, _
                        $aNum, _
                        $aNum, _
                        $aNum) & $unit[$i] & $retc
        $num = StringTrimRight($num, 4)
        $i += 1
WEnd
$ling = StringSplit($retc, '零', 2)
For $i = 0 To UBound($ling) - 1
        If StringLen($ling[$i]) = 1 Then _ArrayDelete($ling, $i)
Next
_ArrayTrim($ling, 1)
MsgBox(0, 0, _ArrayToString($ling, '零', 1))

再试试

afan 发表于 2013-3-3 16:18:38

回复afan
再试试,嗯,好像是,不过这个问题不大,判断处理下有没有,加下就行了
还有,忘了题目了,如 ...
netegg 发表于 2013-3-3 15:29 http://www.autoitx.com/images/common/back.gif


    测试 15700970090560901 看看,应该存在3个零才是
页: [1] 2
查看完整版本: 字串问题 求解