Странное поведение из `std :: wstringstream` при чтении из потока, состоящего в основном из символов UTF-8 - PullRequest
0 голосов
/ 02 апреля 2019

Я имею дело с ошибкой для API REST на основе C ++, который запускает команды Windows, такие как net start и возвращает вывод в JSON (используя nlohmann::json)

Изначально код использует std::stringstream, вставляет в нее весь вывод команды и возвращает строковое представление, используя str(), затем эта строка вставляется в объект nlohmann::json. Это хорошо работает для UTF-8, для UTF-16, std::stringstream не является правильным выбором.

У нас была проблема с клиентом, у которого была служба Windows с символом, отличным от UTF-8, который, хотя и анализировался std::stringstream без каких-либо отклонений, вызывал проблемы при вставке в объект JSON как не являющийся символом UTF-8.

Чтобы исправить это, самым очевидным решением было использование std::wstringstream, чтобы он возвращал wstring, который я бы преобразовал в std::string (наш API использует версию basic_string<char>) с использованием std::wstring_convert. Я делаю это таким образом, код компилируется, я запускаю API, чтобы увидеть, решена ли проблема, и мне возвращается с выводом, который состоит из всех китайских символов и множества нулей (\ u0000).

Это было довольно странное поведение, вывод команды net start в основном все символы UTF-8, это подмножество широких символов, их правильное чтение не должно быть проблемой, верно? Глядя на шестнадцатеричное представление символа за итерацией символа std::wstring объекта, который выглядел как wstringstream, кажется, что он читает несколько байтов выходных данных этой команды, и, таким образом, шестнадцатеричный вывод соответствует кодовым точкам Unicode для китайских символов.

Мой главный вопрос -

Возможно ли при использовании std::wstringstream для чтения потока, состоящего в основном из символов UTF-8, он считывает несколько байтов за раз, поскольку представляет многобайтовые символы (wchar_t)? Таким образом, вместо английских символов UTF-8 можно получить китайские символы UTF-16 (или какой-либо другой язык в этой плоскости UTF-16, основанный на шестнадцатеричном представлении)?

Я целый день колотил по голове, даже использование std::u16string с использованием чего-то вроде using u16stream = basic_stringstream<char16_t> приводило к тому же результату. Единственный другой вариант, по-видимому, заключается в проверке выходной строки побайтно, чтобы проверить, является ли символ допустимым UTF-8 или нет.

Спасибо за помощь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...