Страницы

Поиск по вопросам

вторник, 28 января 2020 г.

UTF8 строка, в нормальную .NET строку

#c_sharp #net #строки #кодировка


Я знаю как перекодировать строки, интересует следующее, какая стандартная кодировка
у строк .NET. Пробовал UTF-32LE, но символы не правильно отображаются.


  Вопрос не о перекодировании, а о кодировке строк .NET.



По просьбе добавлю код:

VlcTrackInfo(int id, string name)
{
    _id = id;

    Encoding utf8 = Encoding.UTF8;
    Encoding utf32 = Encoding.GetEncoding("UTF-32LE");
    byte[] text = Encoding.Convert(utf8, utf32, utf8.GetBytes(name));
    _name = utf32.GetString(text);
}


Если зациклить внимание на том что в .NET не важно какая кодировка у строки, то тут
думаю стоит внести поправку.

Строка которую я получаю, состоит не из wide символов, а из ansii, которые закодированы
в utf8 кодировку для поддержки извлечения wide символов. Т.е. если я к примеру, подключу
библиотеку к c++-cli проекту и буду перекодировать строку там, то при использовании
того же MultiByteToWideChar с указанием кодировки строки как CP_UTF8, я получу читаемую
строку (но каким-то образом остается 1 лишний символ). Так же при использовании std::wstring_convert>,
снова получаю нормальную читаемую строку.

На скриншоте видно, что testStringDotNet имеет ровно такое же значение, как и принятое
функцией входным параметром:



Если я правильно понимаю, то Encoding.GetBytes отдает массив байт как ubyte, но не
byte за счет чего и происходит неверное декодирование.
    


Ответы

Ответ 1



Слово "кодировка" применимо только при хранении строки как массива байт. Не может в string лежать UTF8 строка или ASCII строка. Т.к. UTF8 или ASCII, или любая другая кодировки - это то, как одни и те же символы записываются в виде разных байт. Но ведь в .net вы работаете с символами, а не с байтами. "A" в utf8 - это тот же символ что "A" в ASCII. Пока строка - это string - вам все равно, какие там внутри байты. Нет никакой "стандартной кодировки". Есть строка. Ее можно превратить в представление в виде байт в любой кодировке. Массив байт можно превратить строку, но для этого нужно указать кодировку для превращения байт в строку. То, что вы называете "перекодированием" строки - это костыль, который обычно применяют для "исправления строки" прочитанной с указанием неверной кодировки. И исправлять это нужно указанием верной кодировки при декодировании оригинального массива байт. Т.е. код выглядит как Есть массив байт Его преобразовали в строку, указав неверную кодировку. Где-то ниже по коду делается попытка "перекодировать" испорченную строку. То, что получается в 2, вы считаете "строкой в неверной кодировке". И поэтому пытаетесь узнать, какая же кодировка верная. И исправить неверную на верную в 3. На самом деле в 2 получилась просто строка. То, что в ней нечитабельный мусор - это последствия того, что вы не угадали с кодировкой при чтении массива байт. И чинить это нужно указанием в 2 той кодировки, в которой строка когда то была в эти байты сохранена. Т.е. проблема не в "кодировке строки", а в том, что вы не угадали с кодировкой массива байт том месте, где из него читается name. Вы, скорее всего, читали массив как utf8, но в байтах была строка в чем-то другом.

Ответ 2



Если вам приходит строка из неуправляемого кода, то принимайте ее как массив байт, а дальше делайте: string str = Encoding.UTF8.GetString(bytes)

Комментариев нет:

Отправить комментарий