Я имею дело с ошибкой для 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 или нет.
Спасибо за помощь!