Совсем не понимаю эти ваши кодировки

Совсем не понимаю эти ваши кодировки

Здравствуйте. Пишу программу. На одном из этапов она должна считывать русские буковки из файла и сравнивать их с чем-либо. Тестирую ввод вот такой программой:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    setlocale( 0, "" );
    wifstream file( "example.rmp" );
    if ( !file )
        wcerr << L"Не удалось открыть файл" << endl;
    wstring temp;
    while ( file >> temp )
        wcout << temp << endl;
    file.close();
    return 0;
}

Вот результат запуска программы:

terminate called after throwing an instance of 'std::ios_base::failure'
  what():  basic_filebuf::underflow invalid byte sequence in file
Aborted (core dumped)

Вот содержание файла( пишу робота-исполнителя на информатику :) )

пока слево не свободно
нц 
    вверх
кц

Причём на символы английского алфавита реакция нормальная.

В чём ошибка «последовательности байт в файле»?

Вот содержание файла

А у тебя файл данных в какой кодировке? cp1251? cp866? UTF-8? UTF-16 (с разными последовательностями байт)?

porshe, вот чего тебе дома не сидится? Есть cp866, есть cp1251, так нет же, UTF-8 ему надо. Ну, получай свой геморрой:

#include <iostream>
#include <fstream>
#include <Windows.h>

using namespace std;

int main()
{
    setlocale(LC_ALL, "Russian");

    ifstream file("example.rmp");
    if ( !file )
        cerr << "Не удалось открыть файл" << endl;
    wchar_t wtemp[500];
    char mbtemp[500];
    while (file.getline(mbtemp, 500)) {
        MultiByteToWideChar(CP_UTF8, 0, mbtemp, 500, wtemp, 500);
        wcout << wtemp << endl;
    }
    file.close();
    return 0;
}

Эта муть родилась после копания по форумам и в MSDN. Но она работает.

Но это ещё цветочки. Ягодки начнутся, когда ты парсить считанные строки будешь.

Учти один момент: UTF-8 — это не wide char. Это multibyte.

Описание MultiByteToWideChar() и иже с ней Unicode Functions .

  • Всё бы хорошо, но у меня не windows :)
  • А разве wifstream, wstring и т.д. работают не с unicode(UTF-8)?

UPD

Поставил на виртуальной машине windows, действительно, ваш код работает. Спасибо.

Учти один момент: UTF-8 — это не wide char. Это multibyte.

Считывать из файла UTF-8 надо как последовательность байт. Я, кстати, сомневаюсь в правильности использования текстового режима чтения. Наверное, корректнее было бы использовать двоичный. Правда тогда возникают сложности с разбивкой на строки: придётся читать просто блоками в буфер, а потом парсить.

Потом буфер с UTF-8 (multibyte) преобразуется в буфер wchar_t.

Так обстоят дела в Винде. Как это организовано в Линуксе — я не разбирался.

Однако в стандартной библиотеке C в <cstdlib> есть функции, связанные с преобразованием Multibyte characters и Multibyte strings. Покопай в этом направлении.

UPD: Ещё довесок по кодировкам, gcc, *nix, wchar_t и пр.

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

Ответить

Вы можете использовать разметку markdown для оформления комментариев и постов. Используйте функцию предпросмотра для проверки корректности разметки.

Пожалуйста, оформляйте исходный код в соответствии с правилами разметки. Для того, чтобы вставить код в комментарий, скопируйте его в текстовое поле ниже, после чего выделите то, что скопировали и нажмите кнопку «код» в панели инструментов. Иначе ваш код может принять нечитаемый вид.

Либо производите оформление кода вручную, следующим образом:

``` #include <iostream> using namespace std; int main() { // ... } ```

Предпросмотр сообщения

Ваше сообщение пусто.