德语变音符号的 c# utf-8 转换问题
c# utf-8 conversion problems with german umlauts
我正在通过节俭协议从 C++ 后端获取一些信息,其中包含带有德语变音符号的字符串(名称)。现在这些变音符号显示为问号,所以我认为我在尝试将它们转换为 utf-8 的正确路径上,尽管 thrift 似乎无论如何都将字符串作为 utf-8 传递。
原始数据来自 postgresql 数据库,并在将其发送到 thrift 接口之前在 c++ 代码中正确显示。
我已经尝试了 3 个不同的版本进行转换,但是 none 它们真的无所不能,我被困在这里了。
版本 1:
private string ConvertUTF8(string str) // str == "Ha�loch, �mely"
{
byte[] bytSrc;
byte[] bytDestination;
string strTo = string.Empty;
bytSrc = Encoding.Unicode.GetBytes(str);
bytDestination = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, bytSrc);
strTo = Encoding.UTF8.GetString(bytDestination);
return strTo; // strTo == "Ha�loch, �mely"
}
版本 2:
private string ConvertUTF8(string str) // str == "Ha�loch, �mely"
{
byte[] bytes = str.Select(c => (byte)c).ToArray();
return Encoding.UTF8.GetString(bytes); // == "Ha�loch, �mely"
}
版本 3:
private string ConvertUTF8(string str) // str == "Ha�loch, �mely"
{
byte[] bytes = Encoding.Default.GetBytes(str);
return Encoding.UTF8.GetString(bytes); // == "Ha?loch, ?mely"
}
如您所见,无论出于何种原因,版本 3 将 � 更改为常规的 ?但结果应该是"Haßloch, Ämely"。知道我做错了什么吗?
编辑 1:
在 c++ 端,字符串从 QString.toStdString() 转换而来,然后传递给 thrift。根据 QT 文档,无论如何,.toStdString() 调用包括到 UTF-8 的转换(另见最佳答案 here)。所以应该正确传递字符串,thrift 接口似乎也在内部使用 UTF-8。
编辑 2:
我试图找出字符串第一次出现的位置,并找到了这一行:
Name = iprot.ReadString();
其中 Name
是字符串类型,iprot
是 Thrift.Protocol.TCompactProtocol
类型
对于 ReadString()
方法,thrift 文档说 Reads a byte[] (via readBinary), and then UTF-8 decodes it
所以这也不是原因...
编辑 3(解决方案):
Marc Gravell 把我推到这个...刚刚替换
Name = iprot.ReadString();
和
var bytes = iprot.ReadBinary();
Name = Encoding.GetEncoding("Windows-1252").GetString(bytes);
编辑 4:
更简单:
var bytes = iprot.ReadBinary();
Name = Encoding.Default.GetString(bytes);
如果您得到 string str
输入,则您 已经丢失了数据 。 string
(System.String
) 在 .NET 中是 always UTF-16。您需要向上游查看输入数据的来源(大概是从某个文件、字节缓冲区、http 客户端或数据库中读取)。 通常只是在您最初解码数据.
时指定正确Encoding
的情况
事后无法修复编码;在上面的代码中,您已经无法挽回地失去了您想要的东西。
我正在通过节俭协议从 C++ 后端获取一些信息,其中包含带有德语变音符号的字符串(名称)。现在这些变音符号显示为问号,所以我认为我在尝试将它们转换为 utf-8 的正确路径上,尽管 thrift 似乎无论如何都将字符串作为 utf-8 传递。
原始数据来自 postgresql 数据库,并在将其发送到 thrift 接口之前在 c++ 代码中正确显示。
我已经尝试了 3 个不同的版本进行转换,但是 none 它们真的无所不能,我被困在这里了。
版本 1:
private string ConvertUTF8(string str) // str == "Ha�loch, �mely"
{
byte[] bytSrc;
byte[] bytDestination;
string strTo = string.Empty;
bytSrc = Encoding.Unicode.GetBytes(str);
bytDestination = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, bytSrc);
strTo = Encoding.UTF8.GetString(bytDestination);
return strTo; // strTo == "Ha�loch, �mely"
}
版本 2:
private string ConvertUTF8(string str) // str == "Ha�loch, �mely"
{
byte[] bytes = str.Select(c => (byte)c).ToArray();
return Encoding.UTF8.GetString(bytes); // == "Ha�loch, �mely"
}
版本 3:
private string ConvertUTF8(string str) // str == "Ha�loch, �mely"
{
byte[] bytes = Encoding.Default.GetBytes(str);
return Encoding.UTF8.GetString(bytes); // == "Ha?loch, ?mely"
}
如您所见,无论出于何种原因,版本 3 将 � 更改为常规的 ?但结果应该是"Haßloch, Ämely"。知道我做错了什么吗?
编辑 1:
在 c++ 端,字符串从 QString.toStdString() 转换而来,然后传递给 thrift。根据 QT 文档,无论如何,.toStdString() 调用包括到 UTF-8 的转换(另见最佳答案 here)。所以应该正确传递字符串,thrift 接口似乎也在内部使用 UTF-8。
编辑 2:
我试图找出字符串第一次出现的位置,并找到了这一行:
Name = iprot.ReadString();
其中 Name
是字符串类型,iprot
是 Thrift.Protocol.TCompactProtocol
对于 ReadString()
方法,thrift 文档说 Reads a byte[] (via readBinary), and then UTF-8 decodes it
所以这也不是原因...
编辑 3(解决方案):
Marc Gravell 把我推到这个...刚刚替换
Name = iprot.ReadString();
和
var bytes = iprot.ReadBinary();
Name = Encoding.GetEncoding("Windows-1252").GetString(bytes);
编辑 4:
更简单:
var bytes = iprot.ReadBinary();
Name = Encoding.Default.GetString(bytes);
如果您得到 string str
输入,则您 已经丢失了数据 。 string
(System.String
) 在 .NET 中是 always UTF-16。您需要向上游查看输入数据的来源(大概是从某个文件、字节缓冲区、http 客户端或数据库中读取)。 通常只是在您最初解码数据.
Encoding
的情况
事后无法修复编码;在上面的代码中,您已经无法挽回地失去了您想要的东西。