如题
现有英文系统,不能在区域语言地方设置为非Unicode使用Chinese语言,必须使用纯英文,(否则还有其它更重要的程序会显示乱码),
有一套Vb开发的程序,之前使用ini写配置文件,配置文件随产品产生,有很多个,里面权威英文,现在想使用程序在里面增加中文,并且将ini编码改为Unicode格式,手动写入了中文,程序中以使用了可以读写中文的控件,但是仍然读出的ini字符为??符号,写入中文时也为??,用strconv也不行,现在实在不知道怎么弄了,请问该怎么办?或者使用xml格式保存配置信息也可以(有节点信息),该怎么写入中文,并正确读出,

解决方案 »

  1.   

    程序中以使用了可以读写中文的控件?你用这个控件读ini文件了吗?如果用了,就是需要显示中文的控件。
      

  2.   

    先确定是读写问题还是显示问题。
    用二进制工具查看文件、用 AscW 取字符编码,确定读写是否正确。
    如果是纯英文环境应该不能正确显示中文的。
      

  3.   

    还有个办法,把汉字转有asc码,读的时候再转回来
      

  4.   

    我使用了可以显示中文的控件,在纯英文环境下,可以从数据库中读出,并保存中文到数据库,只是不能将中文保存到ini,也不能从我手动写的ini(ini编码被我手动改为Unicode了),中读取中文
      

  5.   

    你试试这个行不行。1、储存Unicode文本。
    Dim tString As String
    Dim tBytes() As Byte
    Dim tFN As Integer
    tString = "小仙妹是个好孩子:)"
    tBytes() = tString
    tFN = FreeFile
    Open "Test.txt" For Binary As #tFN
      Put #tFN, 1, tBytes()
    Close #tFN
    读取Unicode文本
    Dim tString As String
    Dim tBytes() As Byte
    Dim tFN As Integer
    tFN = FreeFile
    Open "Test.txt" For Binary As #tFN
      ReDim tBytes(LOF(tFN) - 1)
      Get #tFN, 1, tBytes()
    Close #tFN
    tString = tBytes()
    MsgBox tString '这里改成用你的控件显示
      

  6.   

    检查一下系统能否识别中文.
    另外,在INI文件中存储中文字段读取时需要注意一下.
      

  7.   

    谢谢小仙妹
    用二进制的方法是可以的,但是我ini中很多节点,这样读写挺麻烦的,要读出来后,用instr判断节点,而且写的时候也不够快的,
    能不能直接读写节点,为中文呢,
    或者使用xml也可以呢,但是我试的结果仍然是保存中文为问号,读不出来的
      

  8.   

    系统为纯英文的,只要程序支持Unicode的,都可以读写中文,我将数据放在数据库中就没问题的,可以完美读写但现在ini中的内容很多,不能放在数据库中的,怎么操作啊,
      

  9.   


    如果我的方法可以,而你读写ini不可以,则说明一个问题:VB在存取ini时候,是按照文本文件处理的。
    以中文为例:
    文本文件存储的代码是“本地编码”。
    在简体系统“本地编码”为GBK编码、在繁体系统“本地编码”为BIG5编码。
    可能由于ini文件是基于文本文件编写的,文本文件在存取过程中会将本地编码与UniCode转换,这个转换过程导致非本地编码不能被识别。如果实在没办法,我给你一个没办法的办法:把所有中文用HEX编码字符串或者Base64字符串代替,16进制字符串或Base64编码字符串除了数字就是英文,在任何系统肯定不会被干扰。在程序里解码成Unicode中文。这个办法的缺点是增加了用户编辑ini文件的难度。但这个办法最容易解决问题。
      

  10.   

    我找了几种代码hex与汉字互转,(汉字)字符与base64互转的,在中文xp系统下都可以正常使用
    但是放到英文系统下,我的txtbox明明写的是中文,但是相同的汉字编译为hex和在中文系统下是不一样的,英文中编译的字符串解码后还是为??,(英文中编译后的字符我在中文和英文系统下解码都为??),而使用中文系统下随便写汉字编码的字符串在英文系统下不能够正常解码,
    base64还有UTF8互转的都是一样,不能够正常编码
      

  11.   

    终于找到了一个可以使用的,网址格式utf8互转的,虽然转出的有点长,但是可以使用了,
    再研究下编码短一点的,
      

  12.   


    原来是这点小事。好多人写的代码都是用Asc和Chr,所以会出现你那种问题。等我马上给你写一个你看看是否好用?
      

  13.   

    试试看哦。Private Sub Command4_Click()
      '编码
      Dim tBytes() As Byte
      tBytes() = "小仙妹是个好孩子:)"
      Text1.Text = UnicodePutToHex(tBytes())
    End SubPrivate Sub Command5_Click()
      '解码
      Dim tBytes() As Byte
      tBytes() = "F0C59DE49B95F266A2E4D79596B505B5A3009200"
      Text1.Text = UnicodeGetByHex(tBytes())
    End Sub
    Function UnicodeGetByHex(ByRef pBytes() As Byte) As Byte()
      '解码器
      Dim tSurBytesIndex As Long
      Dim tSurBytesLength As Long
      Dim tDesBytes() As Byte
      Dim tDesBytesIndex As Long
      Dim tDesBytesLength As Long
      Dim tHEXTable() As Byte
      Dim tUnHEXTable() As Byte
      Dim tBitIndex As Long  tHEXTable() = "0123456789ABCDEF"
      
      ReDim tUnHEXTable(255)
      
      For tBitIndex = 0 To 15
        tUnHEXTable(tHEXTable(tBitIndex * 2)) = tBitIndex
      Next
      
      tSurBytesLength = UBound(pBytes())
      tDesBytesLength = (tSurBytesLength + 1) \ 4 - 1
      
      ReDim tDesBytes(tDesBytesLength)
      
      For tSurBytesIndex = 0 To tSurBytesLength Step 2
        
        tDesBytesIndex = tSurBytesIndex \ 4
        
        If CBool(tSurBytesIndex Mod 4) Then
            tDesBytes(tDesBytesIndex) = tDesBytes(tDesBytesIndex) Or tUnHEXTable(pBytes(tSurBytesIndex)) * 16
          Else
            tDesBytes(tDesBytesIndex) = tDesBytes(tDesBytesIndex) Or tUnHEXTable(pBytes(tSurBytesIndex))
        End If
        
      Next
      
      UnicodeGetByHex = tDesBytes()
    End FunctionFunction UnicodePutToHex(ByRef pBytes() As Byte) As Byte()
      '编码器
      Dim tSurBytesIndex As Long
      Dim tSurBytesLength As Long
      Dim tDesBytes() As Byte
      Dim tDesBytesIndex As Long
      Dim tDesBytesLength As Long
      Dim tHEXTable() As Byte
      
      tHEXTable() = "0123456789ABCDEF"
      
      tSurBytesLength = UBound(pBytes())
      tDesBytesLength = (tSurBytesLength + 1) * 4 - 1
      
      ReDim tDesBytes(tDesBytesLength)
      
      For tDesBytesIndex = 0 To tDesBytesLength Step 2
         
        tSurBytesIndex = tDesBytesIndex \ 4
        
        If CBool(tDesBytesIndex Mod 4) Then
            tDesBytes(tDesBytesIndex) = tHEXTable((pBytes(tSurBytesIndex) \ 16) * 2)
          Else
            tDesBytes(tDesBytesIndex) = tHEXTable((pBytes(tSurBytesIndex) Mod 16) * 2)
        End If
      Next
      
      UnicodePutToHex = tDesBytes()
    End Function
      

  14.   

    谢谢小仙妹,用你的代码,将编码的字符节省了不少哈
    以前编码 "小仙妹" :%E5%B0%8F%E4%BB%99%E5%A6%B9
    用你的代码编码"小仙妹"为:1126CEE4
    非常感谢哈
      

  15.   

    Dim tBytes() As Byte
    tBytes() = "小仙妹是个好孩子:)"小仙妹很可爱的:)
      

  16.   


    你肯定发错了。
    “小仙妹”应该是F0C59DE49B95
    1126CEE4解码后是“我们”既然这个办法奏效,那么Base64也能奏效。只不过你找到的不是Bytes转Base64,而是字符串转Base64,中间发生了代码页转换。其实你要做的是不想让系统帮你转换代码,而是用系统的Unicode。但系统自作聪明,画蛇添足地做代码页转换。由于好多人写程序过度依赖现成的函数和系统自带的API,所以最底层的一环如果出了问题,那么就会特别困惑。我上述代码是从代码换算角度实现的,代码互相转换的过程根本就没经过VB的字符串函数,完全是Byte数组之间的换算,所以它才奏效。
      

  17.   

    嗯就是,编码字是从虚拟机中直接Ctrl+C的,可能没有真正复制过来的,我都没有发现哎,小仙妹很细心啊
    最近要用到编码转换,但是一直都没怎么搞明白,vb中Unicode关系,以后如果深入学习的话,还要向小仙妹学习啊
      

  18.   

    半角字符"ABCDEFG"Unicode:
    41 00 42 00 43 00 44 00 45 00 46 00 47 00ANSI:
    41 42 43 44 45 46 47Unicode每个字符用2Byte、ANSI每个字符用1Byte。转换方法是地址乘2,简单扩展。全角字符"小仙妹"Unicode:
    0F 5C D9 4E B9 59GBK:
    D0 A1 CF C9 C3 C3GBK和Unicode编码不同,没有简单对应关系。需要映射表转换。混合字符"KiteGirl小仙妹"
    Unicode:4B 00 69 00 74 00 65 00 47 00 69 00 72 00 6C 00 0F 5C D9 4E B9 59
    ANSI & GBK:4B 69 74 65 47 69 72 6C D0 A1 CF C9 C3 C3由于两者长度不同,需要判断是半角还是全角。如果半角结束遇到全角,就要从遇到的全角开始计算奇偶拍节。这种ANSI & GBK混合字符串也就是中文文本文件实际的编码。这个需要状态机区分全角、半角,然后再用各自方法转换。英文系统不能将GBK编码正确转换成Unicode,也不能将Unicode正确转换成GBK。而String保存为文件是一个从Unicode到GBK & ANSI编码转换的过程;从文件读取String是一个GBK & ANSI转换为Unicode的过程。好多涉及文本文件的函数会自动进行这个转换,因此造成你这种混乱。最后,我十分遗憾地告诉你一件事:我上述函数写错了一个地方——16进制的"A"应该是41,但我返回的是14。高位和低位发生颠倒。编码解码函数虽然可以正常使用。但从专业角度来讲这是错误的。下面是纠正后的代码:
    Function UnicodeGetByHex(ByRef pBytes() As Byte) As Byte()
      '解码器
      Dim tSurBytesIndex As Long
      Dim tSurBytesLength As Long
      Dim tDesBytes() As Byte
      Dim tDesBytesIndex As Long
      Dim tDesBytesLength As Long
      Dim tHEXTable() As Byte
      Dim tUnHEXTable() As Byte
      Dim tBitIndex As Long  tHEXTable() = "0123456789ABCDEF"
      
      ReDim tUnHEXTable(255)
      
      For tBitIndex = 0 To 15
        tUnHEXTable(tHEXTable(tBitIndex * 2)) = tBitIndex
      Next
      
      tSurBytesLength = UBound(pBytes())
      tDesBytesLength = (tSurBytesLength + 1) \ 4 - 1
      
      ReDim tDesBytes(tDesBytesLength)
      
      For tSurBytesIndex = 0 To tSurBytesLength Step 2
        
        tDesBytesIndex = tSurBytesIndex \ 4
        
        If CBool(tSurBytesIndex Mod 4) Then
            tDesBytes(tDesBytesIndex) = tDesBytes(tDesBytesIndex) Or tUnHEXTable(pBytes(tSurBytesIndex))
          Else
            tDesBytes(tDesBytesIndex) = tDesBytes(tDesBytesIndex) Or tUnHEXTable(pBytes(tSurBytesIndex)) * 16
        End If
        
      Next
      
      UnicodeGetByHex = tDesBytes()
    End FunctionFunction UnicodePutToHex(ByRef pBytes() As Byte) As Byte()
      '编码器
      Dim tSurBytesIndex As Long
      Dim tSurBytesLength As Long
      Dim tDesBytes() As Byte
      Dim tDesBytesIndex As Long
      Dim tDesBytesLength As Long
      Dim tHEXTable() As Byte
      
      tHEXTable() = "0123456789ABCDEF"
      
      tSurBytesLength = UBound(pBytes())
      tDesBytesLength = (tSurBytesLength + 1) * 4 - 1
      
      ReDim tDesBytes(tDesBytesLength)
      
      For tDesBytesIndex = 0 To tDesBytesLength Step 2
         
        tSurBytesIndex = tDesBytesIndex \ 4
        
        If CBool(tDesBytesIndex Mod 4) Then
            tDesBytes(tDesBytesIndex) = tHEXTable((pBytes(tSurBytesIndex) Mod 16) * 2)
          Else
            tDesBytes(tDesBytesIndex) = tHEXTable((pBytes(tSurBytesIndex) \ 16) * 2)
        End If
      Next
      
      UnicodePutToHex = tDesBytes()
    End Function
    纠正后的"小仙妹是个好孩子:)"编码后应该是
    0F5CD94EB9592F662A4E7D59695B505B3A002900而你如果用Unicode保存这句话(记事本"另存为"Unicode格式),用UltreEdit打开应该看到
    FF FE 这个是Unicode文件头多余标志。
    0F 5C D9 4E B9 59 2F 66 2A 4E 7D 59 69 5B 50 5B 3A 00 29 00作为一个正确的HEX编码器,必须和UEdit的结果一致。