wostream无法输出wstring [英] wostream fails to output wstring

查看:264
本文介绍了wostream无法输出wstring的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Visual Studio C ++ 2008(Express).当我运行以下代码时,wostream(std::wcoutstd::wfstream)都在遇到的第一个非ASCII字符(在这种情况下为中文)中停止输出.纯ASCII字符可以正常打印.但是,在调试器中,我可以看到wstring实际上用汉字正确填充,而output << ...实际上正在执行.

I am using Visual Studio C++ 2008 (Express). When I run the below code, the wostream (both std::wcout, and std::wfstream) stops outputting at the first non-ASCII character (in this case Chinese) encountered. Plain ASCII characters print fine. However, in the debugger, I can see that the wstrings are in fact properly populated with Chinese characters, and the output << ... is in fact getting executed.

Visual Studio解决方案中的项目设置被设置为使用Unicode字符集".为什么std::wostream无法输出超出ASCII范围的Unicode字符?

The project settings in the Visual Studio solution are set to "Use Unicode Character Set". Why is std::wostream failing to output Unicode characters outside of the ASCII range?

void PrintTable(const std::vector<std::vector<std::wstring>> &table, std::wostream& output) {
    for (unsigned int i=0; i < table.size(); ++i) {
        for (unsigned int j=0; j < table[i].size(); ++j) {
            output << table[i][j] << L"\t";
        }
        //output << std::endl;
    }
}


void TestUnicodeSingleTableChinesePronouns() {
    FileProcessor p("SingleTableChinesePronouns.docx");
    FileProcessor::iterator fileIterator;
    std::wofstream myFile("data.bin", std::ios::out | std::ios::binary);
    for(fileIterator = p.begin(); fileIterator != p.end(); ++fileIterator) {
        PrintTable(*fileIterator, myFile);
        PrintTable(*fileIterator, std::wcout);
        std::cout<<std::endl<<"---------------------------------------"<<std::endl;
    }
    myFile.flush();
    myFile.close();
}

推荐答案

默认情况下,std :: wcout和std :: wofstream用于某些操作的语言环境是"C"语言环境,支持非ASCII字符(或C ++基本字符集以外的任何字符).将语言环境更改为支持您要使用的字符的语言环境.

By default the locale that std::wcout and std::wofstream use for certain operations is the "C" locale, which is not required to support non-ascii characters (or any character outside C++'s basic character set). Change the locale to one that supports the characters you want to use.

不幸的是,在Windows上要做的最简单的事情是使用旧版代码页,但是您确实应该避免这种情况.旧版代码页是个坏消息.相反,您应该使用Unicode,无论是UTF-8,UTF-16还是其他类型.另外,您还必须解决Windows不幸的控制台模型的问题,该模型使对控制台的写入与对其他类型的输出流的写入非常不同.您可能需要查找或编写自己的输出缓冲区来专门处理控制台(或者提交一个错误,要求Microsoft对其进行修复).

The simplest thing to do on Windows is unfortunately to use legacy codepages, however you really should avoid that. Legacy codepages are bad news. Instead you should use Unicode, whether UTF-8, UTF-16, or whatever. Also you'll have to work around Windows' unfortunate console model that makes writing to the console very different from writing to other kinds of output streams. You might need to find or write your own output buffer that specifically handles the console (or maybe file a bug asking Microsoft to fix it).

这是控制台输出的示例:

Here's an example of console output:

#include <Windows.h>

#include <streambuf>
#include <iostream>

class Console_streambuf
    : public std::basic_streambuf<wchar_t>
{
    HANDLE m_out;
public:
    Console_streambuf(HANDLE out) : m_out(out) {}

    virtual int_type overflow(int_type c = traits_type::eof())
    {
        wchar_t wc = c;
        DWORD numberOfCharsWritten;
        BOOL res = WriteConsoleW(m_out, &wc, 1, &numberOfCharsWritten, NULL);
        (void)res;
        return 1;
    }
};

int main() {
    Console_streambuf out(GetStdHandle(STD_OUTPUT_HANDLE));
    auto old_buf = std::wcout.rdbuf(&out);
    std::wcout << L"привет, 猫咪!\n";
    std::wcout.rdbuf(old_buf); // replace old buffer so that destruction can happen correctly. FIXME: use RAII to do this in an exception safe manner.
}

您可以将UTF-8输出到这样的文件中(尽管我不确定VS2008是否支持codecvt_utf8_utf16):

You can do UTF-8 output to a file like this (although I'm not sure VS2008 supports codecvt_utf8_utf16):

#include <codecvt>
#include <fstream>

int main() {
    std::wofstream myFile("data.bin", std::ios::out | std::ios::binary);
    myFile.imbue(std::locale(myFile.getloc(),new std::codecvt_utf8_utf16<wchar_t>));

    myFile << L"привет, 猫咪!";
}

这篇关于wostream无法输出wstring的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆