Каким образом можно преобразовать строку типа char*, которая содержит символы в формате Unicode?

Как мне корректно преобразовать строку в формате char*, возвращаемую внешней C библиотекой, содержащую Unicode escape-последовательности (например, "\u0422\u0420\u0415\u041D\u0414"), в читаемый вид (например, "ТРЕНД")? Предыдущая попытка преобразования через std::string и MultiByteToWideChar в std::wstring не увенчалась успехом. Кроме того, поскольку работа codecvt_utf8_utf16 помечена как устаревшая (deprecated), я ищу альтернативное решение.
  • 4 декабря 2023 г. 14:50
Ответы на вопрос 2
Преобразование Unicode escape-последовательностей в UTF-8 символы на C/C++ может быть достигнуто различными способами. В данной ситуации, преобразовать `\uXXXX` последовательности в UTF-8 строки можно с помощью следующего алгоритма:

1. Разобрать исходную строку и найти все `\uXXXX` последовательности.
2. Преобразовать каждую найденную последовательность в соответствующий Unicode символ (в Unicode code point).
3. Конвертировать полученные Unicode code points в UTF-8.

Вот пример простого реализованного конвертера на C++:

```cpp
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <codecvt>
#include <locale>

std::string unicode_escape_to_utf8(const std::string& str) {
    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> convert;
    std::wstring wresult;
    
    for (size_t i = 0; i < str.length();) {
        if (i + 6 <= str.length() && str[i] == '\\' && str[i+1] == 'u') {
            std::wstringstream wss;
            wss << std::hex << str.substr(i + 2, 4);
            unsigned int cp;
            wss >> cp;
            wresult += static_cast<wchar_t>(cp);
            i += 6; // Пропустим последовательность в формате \uXXXX
        } else {
            // Для обработки ASCII символов воспользуемся простым преобразованием
            wresult += str[i];
            i++;
        }
    }

    return convert.to_bytes(wresult);
}

int main() {
    std::string unicode_string = "\\u0422\\u0420\\u0415\\u041D\\u0414";
    std::string utf8_string = unicode_escape_to_utf8(unicode_string);
    
    std::cout << utf8_string << std::endl; // Выведет "ТРЕНД"

    return 0;
}
```
Обратите внимание, что `std::wstring_convert` и `std::codecvt_utf8` тоже были объявлены устаревшими в C++17, но по состоянию на 2023 год эти классы все еще доступны и работают в большинстве компиляторов. Вы можете использовать их до тех пор, пока не появятся наилучшие альтернативы в стандартной библиотеке C++ или в сторонних библиотеках.

Если вы ищете альтернативу без использования устаревших компонентов стандартной библиотеки C++, рассмотрите использование сторонних библиотек, таких как ICU (International Components for Unicode), которая предлагает широкий спектр инструментов для работы с Unicode.
Если я правильно понял чего выхотите добиться, то можете попробовать данную библиотекуhttps://github.com/nemtrif/utfcppКрайне простая и компактная
Похожие вопросы