我正在尝试将代码从VC++迁移到.net。VC++代码使用WinAPI提供的MultibyteToWideChar和WideCharToMultiByte函数。我尝试在System.Text.Encoding中使用.NET类,但它并不适用于所有编码。还有其他方法来完成这个转换吗?下面的代码片段有什么问题?
以下是我的C#代码:
public static string MultiByteToWideChar(string input, int codepage)
{
Encoding e1 = Encoding.GetEncoding(codepage);
Encoding e2 = Encoding.Unicode;
//byte[] source = e1.GetBytes(input);
byte[] source = MBCSToByte(input);
byte[] target = Encoding.Convert(e1, e2, source);
return e2.GetString(target);
}
public static string WideCharToMultiByte(string input, int codepage)
{
Encoding e1 = Encoding.Unicode;
Encoding e2 = Encoding.GetEncoding(codepage);
byte[] source = e1.GetBytes(input);
byte[] target = Encoding.Convert(e1, e2, source);
return Encoding.GetEncoding(codepage).GetString(target);
}
private static byte[] MBCSToByte(string s)
{
byte[] b = new byte[s.Length];
int i = 0;
foreach (char c in s)
b[i++] = (byte)c;
return b;
}MultiByteToWideChar只为代码页1255工作,而不是为866年工作。
WideCharToMultiByte不适用于代码页1251。
发布于 2016-11-10 19:26:42
MultiByteToWideChar()转换编码的字节(不是字符!)到Unicode字符。
WideCharToMultiByte()将Unicode字符转换为编码字节(不是字符!)。
在.NET中,string类型始终是Unicode字符序列(在UTF-16字节编码中)。因此,使用string来保存编码的字节是完全错误的。
在MultiByteToWideChar()函数中,假设输入string包含16位代码页编码8位字节的Unicode字符。您正在将Unicode字符转换为-is到byte[]数组,然后将该代码页编码的数组转换为UTF-16 byte[]数组,然后将其转换为UTF-16 string。这将工作良好的当且仅当最初的假设是正确的。这通常不是这样的,除非您的输入一开始就损坏了。
在WideCharToMultiByte()函数中,将输入string转换为UTF-16 byte[]数组,然后将该数组转换为代码页编码的byte[]数组。到目前为止,还可以使用Encoding.GetBytes()直接从UTF-16 string到代码页编码的byte[],而不需要使用Encoding.Convert() )。但是,您使用相同的代码页将代码页编码的byte[]数组转换回UTF-16 string,从而取消了您所做的一切。输出string的值将与输入string相同(前提是指定的代码页支持输入string中的所有Unicode字符,否则在第一次代码页转换期间将出现数据丢失)。
话虽如此,正确的代码应该更像这样:
public static string MultiByteToWideChar(byte[] input, int codepage)
{
return Encoding.GetEncoding(codepage).GetString(input);
}
public static byte[] WideCharToMultiByte(string input, int codepage)
{
return Encoding.GetEncoding(codepage).GetBytes(input);
}不要使用string来保存编码的字节,而是使用实际的byte[]数组。
发布于 2016-11-10 12:26:03
string是一个字符串,不是字节流。当您将二进制数据包装在string中时,您已经丢失了。
如果希望在编码之间进行适当的转换,请确保使用byte[]。string已经为这些字节赋予了意义。.NET的string与C的char*不是一回事。保留string用于string,并使用byte[]进行持久性、联网等。
https://stackoverflow.com/questions/40527497
复制相似问题