wfstream не пишет - PullRequest
       1

wfstream не пишет

3 голосов
/ 04 октября 2010

У меня есть следующий фрагмент кода на C ++:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(){
    wstring ws1 = L"Infinity: \u2210";
    wstring ws2 = L"Euro: €";

    wchar_t w[] = L"Sterling Pound: £";

    wfstream out("/tmp/unicode.txt");
    out.write(ws1.c_str(), ws1.size());
    out << ws1 << endl << ws2 << endl << w << endl;
    out.flush();
    out.close();
}

Программа компилируется без проблем, но файл никогда не открывается, не говоря уже о записи.Более того, если я использую std::wcout, я все равно не получаю правильный вывод, просто ? для символов бесконечности и фунта.

Моя система - g ++ 4.4.3 под управлением Ubuntu Linux 10.4 64bit.1008 *

Ответы [ 2 ]

3 голосов
/ 04 октября 2010

В стандарте нет определения того, как широкий символьный поток преобразуется в символьное устройство, и вам необходимо поэкспериментировать с вашей системой, чтобы выяснить, что происходит. Обычно установка локального через C должна работать для потоков ввода / вывода std std :: cin / std :: cout.

setlocale("");  // Loads the local that the machine is configured for (see you config)
                // If it is not configured it default to the "C" locale

Объекты файлового потока не могут автоматически извлекать локальный, поэтому иногда стоит явно указать локальный поток.

std::locale   defaultLocale(""); // from machine config
std::wfstream out;
out.imbue(defaultLocale);        // imbue must be done before opening
                                 // otherwise it is ignored.

out.open("/tmp/unicode.txt");

Давайте сделаем несколько тестов, чтобы убедиться, что вы действительно пишете:

if (!out)
{
    std::cout << "Failed to open file\n";
}

В качестве примечания:

out.write(ws1.c_str(), ws1.size()); // size() is the number of characters (wide)
                                    // write is expecting the number of bytes.

Другое примечание:

out.flush();    // flush() happens automatically when the file is closed
out.close();    // close() happens automatically when the stream is destroyed.
                // So technically it is better not to use these
                // as they are specific to file streams which will prevent you from
                // easily replacing this with a generic stream
1 голос
/ 04 октября 2010

Всегда устанавливайте локаль первой ... делайте locale::global( locale( "" ) );. До этого вы находитесь в обычном режиме C, который ничего не знает о UTF-8.

В Дарвине это не работает, поэтому мне нужно сделать setlocale( LC_ALL, "" );, но тогда ваша программа работает для меня.

Редактировать

Упс, у вас получилось по две погрешности одновременно. Открытие wfstream с открытым режимом по умолчанию не создает файл. Я случайно исправил это до wofstream перед запуском вашей программы, а потом забыл, что сделал. Сожалею. Итак:

wofstream out("/tmp/unicode.txt");

или

wfstream out("/tmp/unicode.txt", ios::in | ios::out | ios::trunc );
...