【轉載】如何用VB6在中文系統下把Unicode編碼的日文字元轉成Shift-JIS編碼
阿新 • • 發佈:2019-01-27
這個題目有點變態,不過有時確實會有這種需求,起碼我就碰到過。同樣變態的需求還有“如何用VB6在日文系統下把Unicode編碼的中文字元轉成GB2312編碼”。這種需求有個比較時髦的名字,叫做“國際對應”。本文將提供幾種解決方法。
一:繁瑣的方法
如果之前看過我貼的那篇VB6中EBCDIC碼和Unicode碼之間的相互轉換方法,可能馬上就想到答案了。沒錯,我們可以用WideCharToMultiByte,把裡面的內碼表改成日文932就行了。WideCharToMultiByte接受的源資料是Unicode編碼的陣列,那麼問題自然就轉變為如何把這個字串轉成陣列。下面有兩種做法:
1 轉成Byte陣列
1PrivateFunction Uni2WChar(str AsString) AsByte()
2 Dim i AsLong 3 Dim idx AsLong 4 Dim iC AsInteger 5 Dim iH AsInteger 6 Dim iL AsInteger 7 Dim byt() AsByte 8
9 idx =010 ' 多定義一位元組,作為結尾'/0'(就像C裡面一樣)11ReDim byt(Len(str) *2+1)
12
13 For i =1ToLen(str)
14 iC = AscW(Mid(str, i, 1))
15 iH = (iC And&HFF00) /& H100
16 If iC <0Then iH = iH +&H100
17 iL = iC And&HFF
18 ' 高低位元組是反著存的19 byt(idx) = iL
20 byt(idx +1) = iH
21 idx = idx +222 Next i
23
24 Uni2WChar = byt
25End Function
2 轉成Integer陣列
其實,大可不必自己大費周折地手動把一個個16位的Unicode字元轉成8位的位元組陣列,直接轉成16位的Integer陣列(VB6的Integer是16位的哦)就行了,剩下的事情交給機器做--從物理上說,存資料的這塊連續記憶體的大小和內容完全和上面是一樣的。所不同的只在邏輯上。
1 PrivateFunction Uni2WChar(str AsString) AsInteger()
2 Dim i AsLong 3 Dim ary() AsInteger 4
5 ReDim ary(Len(str))
6
7 For i =1ToLen(str)
8 ary(i -1) = AscW(Mid(str, i, 1))
9 Next i
10
11 Uni2WChar = ary
12End Function That's all!記得要把那個WChar2XXX函式的引數型別改成Integer陣列。
二:最簡捷的方法
StrConv(string, conversion, LCID)
還記得StrConv函式的最後一個引數嗎?MSDN上是這麼說的:
LCID Optional. The LocaleID, if different than the system LocaleID. (The system LocaleID is the default.)
大部分的時候都是用VB6提供的預設值。現在這個引數就派上用場了,下面是例子:
1Dim byt() AsByte2' 把"一二三"轉成日文Shift-JIS編碼,LCID=0x04113byt = StrConv("一二三", vbFromUnicode, &H411)
4' 把"一二三"轉成中文GB2312編碼,LCID=0x08045byt = StrConv("一二三", vbFromUnicode, &H804)
一:繁瑣的方法
如果之前看過我貼的那篇VB6中EBCDIC碼和Unicode碼之間的相互轉換方法,可能馬上就想到答案了。沒錯,我們可以用WideCharToMultiByte,把裡面的內碼表改成日文932就行了。WideCharToMultiByte接受的源資料是Unicode編碼的陣列,那麼問題自然就轉變為如何把這個字串轉成陣列。下面有兩種做法:
1 轉成Byte陣列
1PrivateFunction Uni2WChar(str AsString) AsByte()
2 Dim i AsLong 3 Dim idx AsLong 4
9 idx =010 ' 多定義一位元組,作為結尾'/0'(就像C裡面一樣)11ReDim byt(Len(str) *2+1)
12
13 For i =1ToLen(str)
14 iC = AscW(Mid(str, i, 1))
15 iH = (iC And&HFF00) /&
16 If iC <0Then iH = iH +&H100
17 iL = iC And&HFF
18 ' 高低位元組是反著存的19 byt(idx) = iL
20 byt(idx +1) = iH
21 idx = idx +222 Next i
23
24 Uni2WChar = byt
25End Function
2 轉成Integer陣列
其實,大可不必自己大費周折地手動把一個個16位的Unicode字元轉成8位的位元組陣列,直接轉成16位的Integer陣列(VB6的Integer是16位的哦)就行了,剩下的事情交給機器做--從物理上說,存資料的這塊連續記憶體的大小和內容完全和上面是一樣的。所不同的只在邏輯上。
1
2 Dim i AsLong 3 Dim ary() AsInteger 4
5 ReDim ary(Len(str))
6
7 For i =1ToLen(str)
8 ary(i -1) = AscW(Mid(str, i, 1))
9 Next i
10
11 Uni2WChar = ary
12End Function That's all!記得要把那個WChar2XXX函式的引數型別改成Integer陣列。
二:最簡捷的方法
StrConv(string, conversion, LCID)
還記得StrConv函式的最後一個引數嗎?MSDN上是這麼說的:
LCID Optional. The LocaleID, if different than the system LocaleID. (The system LocaleID is the default.)
大部分的時候都是用VB6提供的預設值。現在這個引數就派上用場了,下面是例子:
1Dim byt() AsByte2' 把"一二三"轉成日文Shift-JIS編碼,LCID=0x04113byt = StrConv("一二三", vbFromUnicode, &H411)
4' 把"一二三"轉成中文GB2312編碼,LCID=0x08045byt = StrConv("一二三", vbFromUnicode, &H804)