Написал в файл, используя std::wofstream. Файл остался пустым

Я написал следующую программу, используя VS2008:

#include <fstream>
int main()
{
    std::wofstream fout("myfile");
    fout << L"Հայաստան Россия Österreich Ελλάδα भारत" << std::endl;
}

Когда я попытался скомпилировать его, IDE спросила меня, хочу ли я сохранить исходный файл в Unicode, я ответил "да, пожалуйста".
Затем я запускаю программу, и myfile появился в папке моего проекта. Я открыл его с помощью блокнота, файл был пуст. Я вспомнил, что блокнот поддерживает только данные ASCII. Я открыл его с WordPad, он все еще был пустым. Наконец маленький гений внутри меня убедил меня взглянуть на размер файла, и неудивительно, что это было 0 байт. Поэтому я перестроил и перезапустил программу, безрезультатно. Наконец я решил спросить очень умных людей на Stackru о том, что мне не хватает, и вот я здесь:)

Отредактировано:

После того, как вышеупомянутые умные люди оставили некоторые комментарии, я решил последовать их совету и переписал программу следующим образом:

#include <fstream>
#include <iostream>
int main()
{
    std::wofstream fout("myfile");
    if(!fout.is_open())
    {
        std::cout << "Before: Not open...\n";
    }
    fout << L"Հայաստան Россия Österreich Ελλάδα भारत" << std::endl;
    if(!fout.good())
    {
        std::cout << "After: Not good...\n";
    }
}

Построил это. Запустил это. И... консоль ясно прочитала, к моему удивлению: "После: не хорошо...". Поэтому я отредактировал свой пост, чтобы предоставить новую информацию, и начал ждать ответов, которые объяснили бы, почему это так и что я мог сделать.:)

3 ответа

Решение

В Visual studio выходной поток всегда записывается в кодировке ANSI и не поддерживает вывод UTF-8.

Что в основном нужно сделать, это создать класс языкового стандарта, установить в него фасет UTF-8 и затем передать его в fstream.

Что происходит, что кодовые точки не преобразуются в кодировку UTF. Так что в принципе это не будет работать под MSVC, поскольку он не поддерживает UTF-8.

Это будет работать под Linux с языком UTF-8

#include <fstream>
int main()
{
    std::locale::global(std::locale(""));
    std::wofstream fout("myfile");
    fout << L"Հայաստան Россия Österreich Ελλάδα भारत" << std::endl;
}

~ И под окнами это будет работать:

#include <fstream>
int main()
{
    std::locale::global(std::locale("Russian_Russia"));
    std::wofstream fout("myfile");
    fout << L"Россия" << std::endl;
}

Так как MSVC поддерживает только кодировки ANSI.

Фасет Codecvt можно найти в некоторых библиотеках Boost. Например: http://www.boost.org/doc/libs/1_38_0/libs/serialization/doc/codecvt.html

MSVC предлагает codecvt_utf8 языковой аспект для этой проблемы.

#include <codecvt>

// ...  
std::wofstream fout(fileName);
std::locale loc(std::locale::classic(), new std::codecvt_utf8<wchar_t>);
fout.imbue(loc);

Я обнаружил, что следующий код работает правильно. Я использую VS2019.

      #include <iostream>
#include <fstream>
#include <codecvt>

int main()
{
    std::wstring str = L"abàdëef€hhhhhhhµa";
    std::wofstream fout(L"C:\\app.log.txt", ios_base::app); //change this to ios_base::in or ios_base::out as per relevance
    std::locale loc(std::locale::classic(), new std::codecvt_utf8<wchar_t>);
    fout.imbue(loc);
    fout << str;
    fout.close();
}
Другие вопросы по тегам