C++ считывание из файла wchar_t

350
28 марта 2017, 13:57

Здравствуйте.

#include <fstream>
#include <string>
using namespace std;
int main(){
    wstring test;
    wchar_t c;
    fstream fin;
    fin.open("test_file");
}

В test_file находится строка, состоящая из символов как русского, так и английского алфавитов. Каким образом можно посимвольно считать всю строку, чтобы на каждой итерации в переменной "с" хранился один символ? Задача состоит в том, чтобы из файла считать строку, к примеру "ТестTest" и чтобы потом команда test.length() вернула не 12, а 8

Answer 1

wchar_t работает с UCS-2 (вариантом UTF-16, строго 2 байта на символ). Текст же, судя по test.length(), закодирован в UTF-8 (1 байт на латиницу, 2-3 байта на прочее).

Для преобразования между кодировками необходимо использовать один из двух способов:

  1. Конвертирующие классы, так называемые фасеты. Для наших целей потребуется codecvt_utf8 (доступен, начиная с C++11):

    #include <fstream>
    #include <string>
    int main()
    {
        std::wstring test;
        std::fstream fin;
        fin.open("test_file");
        std::locale loc(std::locale(), new std::codecvt_utf8<char32_t>);
        ofs.imbue(loc);
        // Дальнейшие операции чтения будут работать уже с корректно 
        // преобразованным потоком `wchar_t`
    }
  2. Стандартные функции Windows API, а именно MultiByteToWideChar:

    // Сначала считываем строку как последовательность `char`. Затем преобразуем
    // считанную строку с помощью этой функции:
    std::wstring decode(const char* src)
    {
        std::vector<wchar_t> buffer;
        buffer.resize(MultiByteToWideChar(CP_UTF8, 0, src, -1, 0, 0));
        MultiByteToWideChar(CP_UTF8, 0, src, -1, &buffer[0], buffer.size());
        return &buffer[0];
    }

Важное замечание: UCS-2 является подмножеством UTF-16, не поддерживающим суррогатные пары. Из-за этого он включает в себя далеко не все символы Unicode. Это необходимо учесть при работе с азиатскими и всякими редкими писменностями.

READ ALSO
Различие define и const

Различие define и const

В чем различие между этими определениями переменной:

279
Как вывести введенную матрицу с++

Как вывести введенную матрицу с++

У меня возникла проблема, как вывести все введенные елементы массива, а не только последнюю строку матрицы

303
Проверить массив при помощи библиотеки assert

Проверить массив при помощи библиотеки assert

Использую библиотеку assert для тестов функцийЕсть функция, которая удаляет повторяющиеся подряд элементы

347
Наименьшее количество чисел в ряду

Наименьшее количество чисел в ряду

Дан ряд чисел(числа принимают значения от 1 до 9) ,нужно вывести какая цифра встречает реже всего в этом ряду,если таких цифр несколько вывести...

268