How to make std::wofstream write UTF-8?

▼魔方 西西 提交于 2020-01-14 04:25:44

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!