日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

VB 字节数组和字符串的转换问题 (StringByte)

發布時間:2025/3/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VB 字节数组和字符串的转换问题 (StringByte) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

VB 字節數組和字符串的轉換問題 (String<>Byte)

Posted by JiaJia 16 March,2009 (2)Comment

一、 前言

   數據類型轉換在編程中經常用到,VB6提供了一整套類型轉換的函數。但是,在進行類型轉換時,有時候僅僅依靠VB提供的函數是不能達到自己的目的的。因此,需要考慮用其他的方法來完成數據類型轉換。本文僅談VB6中字節數組和字符串的相互轉換過程中應注意的問題及其解決辦法。

   在Visual Basic中使用Byte數組主要是為了32位API函數的參數傳遞和函數的返回。在32位的Visual Basic版本中,字符串被假定為Unicode字符,其中每個字符占用兩個字節。系統自動地將Unicode的兩個連續字節轉換成1個字節的ANSI字符。但是,如果該字符串包含二進制數據,其內容將變得很難理解。例如,一個漢字是兩個字節,在Visual Basic 6.0中的長度就只是1,這將給我們計算單個漢字的國標碼帶來一些麻煩。有了Byte數組,這些問題就將迎刃而解。

   另外,Visual Basic中的字符串和C語言中的字符串有一些不同,本文將給出一個函數,把C字符串轉換成Visual Basic字符串。

二、 用Byte數組代替字符串

   Byte數組包含的是0-255之間的ASCII碼字符,它不會象字符串那樣被系統作預處理。你可以在很多API函數中用來Byte數組代替字符串。

   例如,下面的代碼中用GetSystemDirectory這個Windows API函數來取得Windows的系統路徑。一共有兩段代碼,一段代碼是傳遞一個字符串來存儲函數返回的系統路徑,另一段代碼是傳遞一個Byte數組來代替字符串。

   為了更好地比較,兩段代碼的不同部分都用黑體標出。讀者可以仔細比較這兩段代碼的差異,這樣您會更深入地理解Byte數組和字符串的差別。

   把這兩段代碼的任何一段放入一個窗體中運行,但擊窗體的空白區域,你將會在窗體中看到Windows的系統路徑。

   下面是使用字符串的代碼:

Private Declare Function GetSystemDirectory Lib "kernel32" Alias "GetSystemDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long

Private Sub
Form_Click()
 
Dim n As Integer
  Dim str As String

  str = Space$(256)
  n = GetSystemDirectory(str,
256)
  str = Left$(str, n)
  Print str
End Sub


   在上面這段代碼中,字符串參數lpBuffer返回Windows的系統路徑。在函數調用之前,將變量預定義成256個字符,并在函數返回時清除多余的字符。

注意:
   在調用API函數之前,通常都需要預先定義一個字符串或者Byte數組以供API函數存儲數據。應該養成這種良好的編程習慣。否則,你的程序有可能崩潰,甚至導致你的系統崩潰。

   下面是使用Byte數組的代碼:

Private Declare Function GetSystemDirectory Lib "kernel32" Alias "GetSystemDirectoryA" (ByRef lpBuffer As Byte, ByVal nSize As Long) As Long

Private Sub
Form_Click()
 
Dim n As Integer
  Dim Buffer() As Byte
  Dim strA as String

  Buffer=Space$(256)
  n = GetSystemDirectory(Buffer(
0), 256)
  strA=StrConv(Buffer,vbUnicode)
  strA = Left$(strA, n)
  Print strA
End Sub


   不知道讀者注意到沒有,第二段代碼中的GetSystemDirectory API函數的聲明已經改變了。第一個參數的聲明由一個ByVal字符串變成了一個ByRef的Byte數組,即由聲明: ByVal lpBuffer As String 變成了 ByRef lpBuffer As Byte

   傳遞字符串時,需要一個ByVal修飾符來把字符串緩沖區傳遞到API函數中,因為字符串變量實際上指示了字符串內容所在的內存地址。在C語言術語中,這代表了一個指向指針的指針。ByVal意味著被傳遞的是一個指向實際字符串內容的內存地址。而在傳遞Byte數組Buffer(0)時,使用ByRef修飾符來傳遞變量,它相當于傳遞了數組中第一個字節內容的地址。事實上,這兩種結果是一樣的。

strA=StrConv(Buffer,vbUnicode)

   這行代碼把Byte數組的二進制數據轉換成一個合法的Visual Basic字符串。

三、 Byte數組和字符串之間的賦值

   為了簡化Byte數組和字符串之間的數據傳遞,允許你在任何動態Byte數組和任何字符串之間直接互相賦值。例如:
Buffer=strA 和 StrA=Buffer

注意:
   當且僅當Byte數組是動態的,而不是固定大小時,你才可以把一個字符串直接賦給一個Byte數組。

   聲明一個動態的Byte數組最簡單的方法是在Dim語句中使用空參數,例如: Dim Buffer() as Byte

   當你把一個字符串賦給一個動態Byte數組時,數組中的字符數將是字符串的字符數目的兩倍。這是因為Visual Basic中字符串使用Unicode,并且每個Unicode字符的實際大小是兩個字節。當把一個ASCII字符轉換成一個Byte數組時,數組中的另一個字節將是0。

   向Unicode的轉換是將每個在緩沖區中的字符轉換成2個字節,從而實際上加倍了存儲在結果字符串的中字節數目,當你認為函數Len(strA)得到的尺寸大小和Unicode轉換后的Ubound(Buffer)函數所返回的尺寸大小相同時,上述特點就不很明顯了。但是,函數LenB(strA)確實返回一個2倍于Len(strA)返回值的數值。這是因為Len函數返回的是字符串中字符的數目,而LenB函數返回的是字符串中字節的數目。一個Unicode串的字符長度僅僅是該串中實際字節數目的一半,這是因為每個Unicode字符2個字節。

四、 字符串轉換成VB字符串

   當我們在VB中調用Win32 API函數時,如果函數的返回值是一個字符串,那一般有如下三種情況:

   1. 函數預先要求你提供一個有固定空間的字符串,以供存儲函數的返回值。

   2. 函數的返回是一個以Null結尾的C字符串,而不是正規的VB字符串。

   3. Win32 API函數有時候會返回另一種類型的字符串。這種類型的字符串在單個緩沖區內保存了多個字符串值,每個值之間用Null隔開,結尾的是兩個Null,一個Null是最后一個字符串值的結尾符,另一個Null是整個字符串的結尾符。這其實就是我們通常在C中遇到的字符串數組。

   第一種情況很好辦,只無原則預先定義好一個空間足夠大的字符串,然后把API函數的返回值賦于這個字符串就可以了。例如,如果你已經知道函數返回值最多不會走過256個字符,可以這樣編碼如下:

Dim sAPIReturn as string
SAPIReturn=Space$(256)
SAPIReturn=API_Function(…)


   對于第二和第三種情況,就必須把返回的C字符串成標準的VB字符串。下面這個函數CStringToVBString把一個以Null結尾的C字符串成VB字符串。

Public Function CStringToVBString(psCString As String) As string
  '參數psCString是一個待轉換的C字符串
  '函數返回Null左邊所有的字符

  dim sReturn as string
  dim iNullCharPos As Integer

  iNullCharPos=InStr(psCString,vbNullChar)
 
if iNullCharPos >0 then
   sReturn =left(psCString, iNullCharPos -1)
 
else
   sReturn =pscstring
 
end if
  CStringToVBString=sReturn
End function


   下面這個過程把一個含有多個C字符串的緩沖區轉換成一個字符串數組。

Public Sub MultiCStringToStringArray(psMultiCString As String, psaStrings() As String)
 
'參數psMultiCString是待轉換的多個C字符串
  '參數psaStrings是返回的VB字符串數組,調用之前它必須是一個動態的空數組

  Dim iNullPos As Integer
  Dim iPrevPos As Integer
  Dim iIdx As Integer

  '初始化字符串數組
  iIdx = 0
  ReDim psaStrings(0 To iIdx 1)
  psaStrings(iIdx
1) = ""
  Do
   iNullPos = InStr(iPrevPos 1, psMultiCString, vbNullChar)
  
If iNullPos > iPrevPos 1 Then
    '把找到的C字符串賦值給字符串數組
    psaStrings(iIdx) = Mid$(psMultiCString, (iPrevPos 1), ((iNullPos - 1) - iPrevPos))
    iIdx = iIdx
1
    ReDim Preserve psaStrings(0 To iIdx)
    iPrevPos = iNullPos
  
Else
    '找到了兩個Null字符,去掉最后一個,然后退出
    ReDim Preserve psaStrings(0 To iIdx - 1)
   
Exit Do
   End If
  Loop
End Sub


   當調用Win32 API函數時,使用這兩個簡單的函數,你可以消除很多冗余的代碼,加快開發步伐。

注意:
   當你為API的返回值預先分配字符串的空間時,一定不要忘了空間內必須包含Null結束符。另外,建議你在使用API時,最好對每個變量都進行聲明,加上下面這句代碼: Option Explicit

五、小結

   VB6中字節數組和字符串的相互轉換是編程中,尤其是新手使用中最為頭疼的問題。本文歸納了軟件開發過程中使用二者的典型情況及其應該注意的問題,供參考。不當之處還請讀者批評指正。

總結

以上是生活随笔為你收集整理的VB 字节数组和字符串的转换问题 (StringByte)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。