wfstream不写

时间:2010-10-04 16:55:20

标签: c++ unicode g++

我在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,我仍然无法获得正确的输出,只有?表示无穷大和英镑符号。

我的系统是运行ubuntu linux 10.4 64bits的g ++ 4.4.3。

2 个答案:

答案 0 :(得分:3)

标准中没有关于如何将宽字符流转换为字符设备的定义,您需要尝试使用系统来查找正在发生的事情。通常设置本地通过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 :(得分:1)

始终先设置区域设置...执行locale::global( locale( "" ) );。在此之前,你处于普通的C模式,它对UTF-8一无所知。

在达尔文,这已经破了,所以我需要做setlocale( LC_ALL, "" );,但那时你的程序适合我。

修改

哎呀,你马上就有两个陷阱。使用默认的openmode打开wfstream不会创建该文件。在运行程序之前,我无意中将其修复为wofstream,然后忘了我做了。抱歉。所以:

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

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