问题
I am redirecting std::wclog
to a file for logging in my program:
std::wclog.rdbuf((new std::wofstream("C:\\path\\to\\file.log", std::ios::app))->rdbuf());
Logging happens by writing to std::wclog
:
std::wclog << "Schöne Grüße!" << std::endl;
Surprisingly I found that the file is being written in ANSI. (This would be totally acceptable for ofstream
and clog
, but I had expected wofstream
and wclog
to produce some kind of unicode output.) I want to be able to log in CYK langugages as well (e.g. user input), so is there a way to get wofstream
to produce UTF-8? The openmode flags seem not to provide for this.
(If there isn’t a platform-independent way, I am on Win7+ 64-bit.)
Edit:
There is an error in the question above. The line
std::wclog << "Schöne Grüße!" << std::endl;
should correctly be
std::wclog << L"Schöne Grüße!" << std::endl;
This is just to demonstrate what I want to do, in real life the wstring
being written to the wofstream
comes out of a class which provides for translation, like
std::wclog << _(L"Best regards") << std::endl;
where
#define _(X) i18n::translate(X)
class i18n {
public:
static std::wstring translate(const std::wstring&);
}
So what I want to do is to write a wstring
to std::wclog
using an wofstring
to put it into a file, and that file should be UTF-8 encoded (without BOM).
回答1:
All you need is to use a UTF8 literal, ie:
std::wclog << u8"Schöne Grüße!" << std::endl;
The result will be
Schöne Grüße!
If you mix ASCII and UTF8 literals, eg:
std::wclog << "Schöne Grüße!" << std::endl << u8"Schöne Grüße!" <<
std::endl;
the non-ASCII characters will be replaced.
Sch?ne Gr??e!
Schöne Grüße!
Unicode literals were added to C++ 11. They were first implemented in Visual Studio 2015. The String and Character Literals page describes the literals that are supported in Visual C++ at the moment.
回答2:
The openmode flags seem not to provide for this.
Because it's nothing to do with the openmode.
Code conversion (i.e. character encoding) is performed by the codecvt
facet of the locale
being used by the stream. You can imbue the ostream with a different locale using a codecvt facet that converts to UTF-8.
But I don't know if that's necessary. I have no idea how Windows behaves, but on sane platforms you would just write narrow character strings containing UTF-8 to clog and the output would be UTF-8, you don't need to use wide streams. UTF-8 is a multibyte encoding using single octets, i.e. narrow characters.
来源:https://stackoverflow.com/questions/38994511/how-to-make-stdwofstream-write-utf-8