Написал в файл, используя std :: wofstream.Файл остался пустым - PullRequest
13 голосов
/ 17 октября 2010

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

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

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

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

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

#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";
    }
}

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

Ответы [ 2 ]

11 голосов
/ 17 октября 2010

MSVC предлагает codecvt_utf8 локаль для этой проблемы

#include <codecvt>

// ...  
std::wofstream fout(fileName);
std::locale loc(std::locale::classic(), new std::codecvt_utf8<wchar_t>);
fout.imbue(loc);
7 голосов
/ 17 октября 2010

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

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

Что происходит, что кодовые точки не преобразуются в кодировку 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;
}

~ А в Windows это будет работать:

#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

...