다음은 대화형 모드(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이라는
클래스를 구현해 보았다.
' 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()
'프로그래밍 > BASIC' 카테고리의 다른 글
손으로 계산하는 긴자리 곱셈표 만들기 with Visual Basic (0) | 2009.03.08 |
---|---|
손으로 만드는 나눗셈 계산표 with Visual Basic (0) | 2009.02.16 |
7비트 ASCII 코드표 만들기 예제 with Visual Basic (0) | 2009.02.16 |
진법(radix) 표 만들기 예제 with Visual Basic (0) | 2009.02.16 |
구구단 출력 예제 for Visual Basic (0) | 2009.02.14 |