gpt4 book ai didi

c++ - wostream 无法输出 wstring

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:36:02 25 4
gpt4 key购买 nike

我正在使用 Visual Studio C++ 2008 (Express)。当我运行下面的代码时,wostream(std::wcoutstd::wfstream)在遇到第一个非 ASCII 字符(在本例中为中文)时停止输出。普通 ASCII 字符打印良好。但是,在调试器中,我可以看到 wstring s 实际上用中文字符正确填充,并且 output << ...实际上正在执行。

Visual Studio 解决方案中的项目设置被设置为“使用 Unicode 字符集”。为什么是std::wostream无法输出 ASCII 范围之外的 Unicode 字符?

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++ 基本字符集之外的任何字符)。将语言环境更改为支持您要使用的字符的语言环境。

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

这是控制台输出的示例:

#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):

#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"привет, 猫咪!";
}

关于c++ - wostream 无法输出 wstring,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11610583/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com