다음은  대화형 모드(interactive mode)에서 진법 변환(radix conversion)하는 Visual Basic 소스 코드이다.

메뉴는 주메뉴 Command: (S)et radix, (A)bout, (Q)uit or E(x)it
와 부메뉴 SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
로 구성되어 있으며, 진법 변환의 핵심은 

         Shared Function ConvertAtoI(s As String, radix As Integer) As Int64
         Shared Function ConvertItoA(num As Int64, int radix As Integer) As String

의 구현과 이용이다. 지원되는 진법은 2진법부터 36진법까지이다.
Visual Basic에는 Java의 StrinngTokener가 구현되어 있지 않다.
그래서 Java의 StrinngTokener와 비슷한 Visual Basic용 StrinngTokener.Token이라는
클래스를 구현해 보았다.

'  Filename: ConvertRadixApp.bas
'            Convert radix in a interactive mode.
'
'  Compile: vbc ConvertRadixApp.bas
'  Execute: ConvertRadixApp
'
'      Date:  2009/02/15
'    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]

Imports System

Namespace StringTokenizer

    Class Token
        Private Dim data As String
        Private Dim delimeter As String
        Private Dim tokens() As String
        Private Dim index As Integer
 
 
        Public Sub New(strdata As String)
            Init(strdata, " ")
        End Sub

        Public Sub New(strdata As String, delim As String)
            Init(strdata, delim)
        End Sub

        Sub Init(strdata As String, delim As String)
            data = strdata
            delimeter = delim
            Dim data2 As String = ""
            Dim isDelim As Boolean = False
            Dim c As String
            For i As Integer = 0 To data.Length - 1
             c = Mid(data, i + 1, 1)
             If delim.Contains(c) Then
                 If Not isDelim Then
                     isDelim = True
           data2 = data2 & c
                 End If
                 Continue For
             End If
         data2 = data2 & c
            Next
            tokens = data2.Split(delimeter.ToCharArray())
            index = 0
        End Sub

        Public Function Count() As Integer
            Count = tokens.Length
        End Function

        Public Function HasMoreTokens() As Boolean
            HasMoreTokens = index < tokens.Length
        End Function

        Public Function NextToken() As String
            If index < tokens.Length Then
                index = index + 1
                NextToken = tokens(index - 1)
                return tokens(index - 1)
            Else
                NextToken = ""
                return ""
            End If
        End Function
    End Class
End Namespace

Namespace MyTestApplication1

    Class ConvertRadixApp

        Shared Sub PrintUsage()
            Console.WriteLine("Usage: ConvertRadixApp")
            Console.WriteLine("Convert radix in a interactive mode, where the maximum radix is 36.")
        End Sub

        Sub PrintAbout()
            Console.WriteLine("    About: Convert radix in a interactive mode.")
        End Sub

        Sub PrintMainMenu()
            Console.WriteLine("  Command: (S)et radix, (A)bout, (Q)uit or E(x)it")
        End Sub

        Sub PrintMainPrompt()
            Console.Write("  Prompt> ")
        End Sub

        Sub PrintSubMenu(srcRadix As Integer, destRadix As Integer)
            Console.WriteLine("    Convert Radix_" & srcRadix & " to Radix_" & destRadix)
            Console.WriteLine("    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit")
        End Sub

        Sub PrintSubPrompt()
            Console.Write("    Input Value>> ")
        End Sub

        Shared BASE36 As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

        Shared Function ConvertItoA(num As Int64, radix As Int32) As String
            Dim tmp As String
            Dim ret As String
            Dim arr As String
            Dim q As Int64
            Dim r As Int64
            Dim isNegative As Boolean = False
            If num < 0L Then
                isNegative = True
                num = -num
            End If
            arr = ""
            q = num
            r = 0L

            While q >= Convert.ToInt64(radix)
                r = q Mod Convert.ToInt64(radix)
                q = Convert.ToInt64(Math.Floor(q / Convert.ToInt64(radix)))
                tmp = Mid(BASE36, Convert.ToInt32(r) + 1, 1)
                arr = arr & tmp
            End While
            tmp = Mid(BASE36, Convert.ToInt32(q) + 1, 1)
            arr = arr & tmp
            If isNegative Then
                arr = arr & "-"
            End If

            ret = ""
            For j As Integer = 0 To arr.Length - 1
               ret = ret & Mid(arr, arr.Length - j - 1 + 1, 1)
            Next
            ConvertItoA = ret
        End Function

        Shared Function ConvertAtoI(s As String, radix As Integer) As Int64
            Dim ret As Int64 = 0L
            Dim isNegative As Boolean = False
            Dim len As Integer = s.Length
            Dim c As char
            Dim i As Integer
            Dim val As Int64 = 0L

            c = s(0)
            If c = "-"c Then
                isNegative = True
            ElseIf c >= "0"c And c <= "9"c Then
                ret = Convert.ToInt64(c) - Convert.ToInt64("0"c)
            ElseIf c >= "A"c And c <= "Z"c Then
                ret = Convert.ToInt64(c) - Convert.ToInt64("A"c) + 10L
            ElseIf c >= "a"c And c <= "z"c Then
                ret = Convert.ToInt64(c) - Convert.ToInt64("a"c) + 10L
            End If
            If (ret >= Convert.ToInt64(radix)) Then
                Console.WriteLine("        Invalid character!")
                ConvertAtoI = ret
               Return ret
            End If

            For i = 1 To len - 1
                c = s(i)
                ret = ret * radix
                If c >= "0"c And c <= "9"c Then
                    val = Convert.ToInt64(c) - Convert.ToInt64("0"c)
                ElseIf c >= "A"c And c <= "Z"c Then
                    val = Convert.ToInt64(c) - Convert.ToInt64("A"c) + 10L
                ElseIf c >= "a"c And c <= "z"c Then
                    val = Convert.ToInt64(c) - Convert.ToInt64("a"c) + 10L
                End If
                If (val >= Convert.ToInt64(radix)) Then
                    Console.WriteLine("        Invalid character!")
                    ConvertAtoI = ret
                   Return ret
                End If
                ret = ret + val
            Next

            If isNegative Then
             ret = -ret
            End If
            ConvertAtoI = ret
            return ret
        End Function

        Function ConvertRadix(s As String, srcRdx As Integer, destRdx As Integer) As String
            Dim val As Int64
            Dim ret As String = ""
            Try
                val = ConvertAtoI(s, srcRdx)
                         ' Console.WriteLine("val = " + val);
                ret = ConvertItoA(val, destRdx)
                ConvertRadix = ret.ToUpper()
                return ret.ToUpper()
            Catch nfx As Exception
                ' Console.WriteLine("    Error: " + nfx.getMessage() + " cantains some invalid character.");
                Console.Write("    Error: ")
                Console.Write(nfx)
                Console.WriteLine(" cantains some invalid character.")
                ret = "????"
                ConvertRadix = ret.ToUpper()
                return ret.ToUpper()
            End Try
        End Function

        Sub  DoConvert(srcRadix As Integer, destRadix As Integer)
            Dim cmd As String
            Dim srcStr As String = ""
            Dim destStr As String = ""
            Console.WriteLine()
            PrintSubMenu(srcRadix, destRadix)
            Try
                Do
                    PrintSubPrompt()
                    cmd = Console.ReadLine()
                    If "main()" = cmd Then
                        return
                    ElseIf "exit()" = cmd Or "quit()" = cmd Then
                        Environment.Exit(0)
                    End If

                    Try
                        Convert.ToInt32(cmd, srcRadix)
                        srcStr = cmd
                        destStr = ConvertRadix(srcStr, srcRadix, destRadix)
                        Console.WriteLine("        ( " & srcStr & " )_" & srcRadix &  "   --->   ( " & destStr & " )_" & destRadix)
                        Console.WriteLine()
                    Catch ex As FormatException
                         Console.Write(cmd + ": ")
                         Console.WriteLine(ex)
                    End Try
                Loop
            Catch ex As Exception
                Console.WriteLine(ex)
            End Try
        End Sub

        Sub DoStart()
            Dim sep() As Char = New Char() { " "c, ","c, Chr(9) }   ' Chr(9) = Tab = \t
            Dim line As String
            Dim cmd As String
            Dim srcRadix As Integer = 10
            Dim destRadix As Integer = 10
            Dim onlyOnce As Boolean = True
            Try
                Do
                    Console.WriteLine()
                    If onlyOnce Then
                        Console.WriteLine("  The supported maximum radix is 36.")
                        onlyOnce = False
                    End If
                    PrintMainMenu()
                    PrintMainPrompt()
                    cmd = Console.ReadLine()
                    If "qQxX".Contains(cmd) And cmd.Length = 1 Then
                        Environment.Exit(0)
                    ElseIf "aA".Contains(cmd) And cmd.Length = 1 Then
                        PrintAbout()
                    ElseIf "sS".Contains(cmd) And cmd.Length = 1 Then
                        Console.Write("  Input the source and target radices (say, 16 2): ")
                        line = Console.ReadLine()
                        Dim tok As StringTokenizer.Token = New StringTokenizer.Token(line, " , \t")
                        While tok.Count() <> 2
                            Console.Write("  Input the source and target radices (say, 16 2): ")
                            line = Console.ReadLine()
                            tok = New StringTokenizer.Token(line, " , \t")
                        End While

                        Try
                            srcRadix = Convert.ToInt32(tok.NextToken())
                            destRadix = Convert.ToInt32(tok.NextToken())
                            DoConvert(srcRadix, destRadix)
                        Catch ex As FormatException
                            Console.WriteLine(ex)
                        End Try
                    End If
                Loop
            Catch ex As Exception
                Console.WriteLine(ex)
            End Try
        End Sub

        ' Java 언어의 main 메소드에 해당하는 Visual Basic의 Main
        Shared Sub Main(ByVal args() As String)
            If args.Length = 0 Then
                 '
            ElseIf args.Length > 0 And "-h" = args(0) Then
                PrintUsage()
                Environment.Exit(1)
            End If
            Dim app As ConvertRadixApp = New ConvertRadixApp()
            app.DoStart()
        End Sub
    End Class
End Namespace




컴파일> vbc ConvertRadixApp.bas

실행> ConvertRadixApp

  The supported maximum radix is 36.
  Command: (S)et radix, (A)bout, (Q)uit or E(x)it
  Prompt> s
  Input the source and target radices (say, 16 2): 10 16

    Convert Radix_10 to Radix_16
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 256
        ( 256 )_10   --->   ( 100 )_16

    Input Value>> main()

  Command: (S)et radix, (A)bout, (Q)uit or E(x)it
  Prompt> s
  Input the source and target radices (say, 16 2): 16 10

    Convert Radix_16 to Radix_10
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> FFFF
        ( FFFF )_16   --->   ( 65535 )_10

    Input Value>> exit()


 

크리에이티브 커먼즈 라이선스
Creative Commons License

 

Posted by Scripter
,