c # utf-8 проблемы с конвертацией немецких умлаутов - PullRequest
0 голосов
/ 13 февраля 2019

Я получаю некоторую информацию из бэкэнда c ++ по экономному протоколу, содержащему строку (имя) с немецкими умлаутами.Теперь эти умлауты отображаются в виде вопросительных знаков, поэтому я думаю, что я на правильном пути, чтобы попытаться преобразовать их в utf-8, хотя thrift, похоже, все равно передает строки как utf-8.

Исходные данные получены избаза данных postgresql и правильно отображается в коде c ++ непосредственно перед отправкой в ​​интерфейс thrift.

Я уже пробовал конвертировать 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 - для чего угоднопричина - меняет � на обычную?но результат должен быть "Haßloch, Ämely".Любая идея, что я делаю неправильно?

edit 1:

На стороне c ++ строка конвертируется из QString.toStdString () и затем передается в Thrift.Согласно QT doc, вызов .toStdString () в любом случае включает преобразование в UTF-8 (см. Также верхний ответ здесь ).Таким образом, строка должна быть передана правильно, и интерфейс Thrift, похоже, также использует UTF-8 для внутреннего использования.

edit 2:

Я попытался выяснить, где будет первое вхождение строки, инашел следующую строку:

Name = iprot.ReadString();

, где Name имеет тип string, а iprot имеет тип Thrift.Protocol.TCompactProtocol

Для метода ReadString() документ thrift doc сообщает:Reads a byte[] (via readBinary), and then UTF-8 decodes it так что это тоже не может быть причиной ...

править 3 (РЕШЕНИЕ):

Марк Гравелл подтолкнул меня к этому ... Просто заменил

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 голосов
/ 13 февраля 2019

Если у вас есть вход string str, вы уже потеряли данные .string (System.String) в .NET - это всегда UTF-16.Вы должны смотреть вверх по течению, откуда бы ни приходили входные данные (предположительно чтение из какого-либо файла, байтового буфера, http-клиента или базы данных).Это обычно просто случай указания правильного Encoding в точке, в которой вы первоначально декодировали данные .

Вы не можете исправить кодирование после факта;в приведенном выше коде вы уже безвозвратно потеряли то, что хотели .

...