wostream fails to output wstring

前端 未结 2 1988
甜味超标
甜味超标 2020-12-16 06:34

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 f

相关标签:
2条回答
  • 2020-12-16 07:00

    Include the following header file

    #include <locale>
    

    at the start of main, add the following line.

    std::locale::global(std::locale("chinese"));
    

    This helps to set the proper locale.

    0 讨论(0)
  • 2020-12-16 07:06

    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.

    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.
    }
    

    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"привет, 猫咪!";
    }
    
    0 讨论(0)
提交回复
热议问题