C#utf-8转换与德国变音符号的问题

时间:2019-02-13 10:15:48

标签: c# qt utf-8 thrift thrift-protocol

我正在通过节俭协议从c ++后端获取一些信息,其中包含带有德国变音符号的字符串(名称)。现在,这些变音符号显示为问号,因此我认为我正在尝试将其转换为utf-8的正确方法,尽管节俭似乎仍然将字符串作为utf-8传递。

原始数据来自一个PostgreSQL数据库,并在将其发送到thrift接口之前将其正确显示在c ++代码中。

我已经尝试了3种不同的版本进行转换,但是我被困在这里,它们都没有真正起作用。

版本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-无论出于何种原因-都会将``更改为常规?但结果应为“ Hameloch,Ämely”。知道我在做什么错吗?

编辑1:

在c ++端,字符串从QString.toStdString()转换,然后传递给thrift。根据QT doc的说法,.toStdString()调用无论如何都包含到UTF-8的转换(另请参见顶部答案here)。因此,应该正确地传递字符串,并且节俭的接口似乎在内部也使用UTF-8。

编辑2:

我试图找出字符串的第一个出现位置,并找到以下行:

Name = iprot.ReadString();

其中Name的类型为字符串,iprot的类型为Thrift.Protocol.TCompactProtocol

对于ReadString()方法,节俭文档说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);

1 个答案:

答案 0 :(得分:5)

如果您输入了string str,说明您已经丢失了数据。 .NET中的stringSystem.String)是始终 UTF-16。您需要向上游看输入数据的来源(大概是从某些文件,字节缓冲区,http客户端或数据库中读取)。 通常只是在最初解码数据时指定正确的Encoding 的一种情况。

事后您无法修复编码;在上面的代码中,您已经无法挽回地丢失了想要的东西