Преобразование шестнадцатеричного в универсальный символ c ++ [дубликат]

для моих проектов Я использую свою библиотеку commons-version https://github.com/raydac/commons-version , она содержит два вспомогательных класса - для синтаксического анализа версии (анализируемая версия может быть сравнена с другой , потому что он сопоставим) и VersionValidator, который позволяет проверять версию для некоторого выражения, такого как ! = ide-1.1.1, & gt; идея-1.3.4-SNAPSHOT; & lt; 1.2.3 [ ! d2]

2
задан Venkatesan 21 August 2014 в 16:19
поделиться

7 ответов

С std c ++

#include <iostream>
#include <locale>
#include <vector>

int main()
{
    typedef std::codecvt<wchar_t, char, mbstate_t> Convert;
    std::wstring w = L"\u20ac\u20ab\u20ac";
    std::locale locale("en_GB.utf8");
    const Convert& convert = std::use_facet<Convert>(locale);

    std::mbstate_t state;
    const wchar_t* from_ptr;
    char* to_ptr;
    std::vector<char> result(3 * w.size() + 1, 0);
    Convert::result convert_result = convert.out(state,
          w.c_str(), w.c_str() + w.size(), from_ptr,
          result.data(), result.data() + result.size(), to_ptr);

    if (convert_result == Convert::ok)
        std::cout << result.data() << std::endl;
    else std::cout << "Failure: " << convert_result << std::endl;
}
0
ответ дан Dieter Lücking 16 August 2018 в 01:04
поделиться

Термин Unicode относится к стандарту кодирования и обработки текста. Это включает кодировки, такие как UTF-8 , UTF-16 , UTF-32 , UCS-2 , .. .

Я предполагаю, что вы программируете в среде Windows, где Unicode обычно относится к UTF-16 .

При работе с Unicode в C ++ я бы рекомендовал библиотеку ICU .

Если вы программируете в Windows, не хотите использовать внешнюю библиотеку и не имеете ограничений в отношении зависимостей платформы , вы можете использовать WideCharToMultiByte .

Пример для ICU:

#include <iostream>
#include <unicode\ustream.h>

using icu::UnicodeString;

int main(int, char**) {
    //
    // Convert from UTF-16 to UTF-8
    //
    std::wstring utf16 = L"foobar";
    UnicodeString str(utf16.c_str());
    std::string utf8;
    str.toUTF8String(utf8);

    std::cout << utf8 << std::endl;
}

Чтобы выполнить именно то, что вы хотите:

// Assuming you have ICU\include in your include path
// and ICU\lib(64) in your library path.
#include <iostream>
#include <fstream>
#include <unicode\ustream.h>
#pragma comment(lib, "icuio.lib")
#pragma comment(lib, "icuuc.lib")

void writeUtf16ToUtf8File(char const* fileName, wchar_t const* arr, size_t arrSize) {
    UnicodeString str(arr, arrSize);
    std::string utf8;
    str.toUTF8String(utf8);

    std::ofstream out(fileName, std::ofstream::binary);
    out << utf8;
    out.close();
}
3
ответ дан Max Truxa 16 August 2018 в 01:04
поделиться
  • 1
    unicode \ ustream.h нет такой файл или ошибка каталога, которую я получаю – Venkatesan 6 December 2013 в 12:18
  • 2
    Вам необходимо загрузить и настроить ICU . – Max Truxa 6 December 2013 в 12:22
  • 3
    Как загрузить и настроить. – Venkatesan 6 December 2013 в 13:36
  • 4
    Нажмите здесь , прокрутите вниз до ICU4C Binary Download и загрузите нужную версию. Извлеките ZIP-файл и поместите извлеченный каталог где-нибудь, вы можете получить к нему доступ из своего проекта. Добавьте 'path-where-you-put-it / icu / include' к вашим проектам: path и 'path-where-you-put-it / icu / lib' (или lib64) к вашему пути библиотеки проектов. – Max Truxa 6 December 2013 в 13:42

Этот код использует WideCharToMultiByte (я предполагаю, что вы используете Windows):

unsigned short wide_str[3] = {0x20ac, 0x20ab, 0x20ac};
int utf8_size = WideCharToMultiByte(CP_UTF8, 0, wide_str, 3, NULL, 0, NULL, NULL) + 1;
char* utf8_str = calloc(utf8_size);
WideCharToMultiByte(CP_UTF8, 0, wide_str, 3, utf8_str, utf8_size, NULL, NULL);

Вам нужно вызвать его дважды: первый раз, чтобы получить номер вывода байты и второй раз, чтобы фактически преобразовать его. Если вы знаете размер выходного буфера, вы можете пропустить первый вызов. Или вы можете просто выделить буфер 2x больше, чем оригинал + 1 байт (для вашего случая это означает 12 + 1 байт) - этого должно быть достаточно.

1
ответ дан mvp 16 August 2018 в 01:04
поделиться

Вы можете использовать Boost.Locale для библиотек Boost: http://www.boost.org/doc/libs/1_55_0/libs/locale/doc/html/index.html

0
ответ дан Nick L. 16 August 2018 в 01:04
поделиться
  • 1
    Не могли бы вы сделать это конкретным? – xin 17 April 2014 в 19:00
  • 2
    Для достижения этой цели Boost.Locale использует современную библиотеку Unicode и Localization: ICU - Международные компоненты для Unicode. – Chris 7 February 2016 в 00:01

Iconv - популярная библиотека, используемая на многих платформах.

0
ответ дан Remy Lebeau 16 August 2018 в 01:04
поделиться

Следующий код может помочь вам,

#include <atlconv.h>
#include <atlstr.h>

#define ASSERT ATLASSERT

int main()
{
    const CStringW unicode1 = L"\x0391 and \x03A9"; // 'Alpha' and 'Omega'

    const CStringA utf8 = CW2A(unicode1, CP_UTF8);

    ASSERT(utf8.GetLength() > unicode1.GetLength());

    const CStringW unicode2 = CA2W(utf8, CP_UTF8);

    ASSERT(unicode1 == unicode2);
}
2
ответ дан Santosh Dhanawade 16 August 2018 в 01:04
поделиться

Наконец-то! С C ++ 11!

#include <string>
#include <locale>
#include <codecvt>
#include <cassert>

int main()
{
    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
    std::string u8str = converter.to_bytes(0x20ac);
    assert(u8str == "\xe2\x82\xac");
}
4
ответ дан sms 16 August 2018 в 01:04
поделиться
  • 1
    Это хорошо, за исключением компиляторов Visual Studio 2015 и 2017, которые не поддерживают std::codecvt с поддержкой char32_t. Но вы можете использовать uint32_t: std::wstring_convert< std::codecvt_utf8<uint32_t>, uint32_t > converter; – Matthew 25 August 2017 в 16:30
  • 2
    Для всех, кто прочитает это сейчас: это устарело в C ++ 17. – handicraftsman 15 June 2018 в 17:38
Другие вопросы по тегам:

Похожие вопросы: