我使用VisualStudio和MFC在C ++中编程(只是偶然)。我用fopen和fprintf写了一个文件。该文件应以UTF8编码。有没有可能这样做?无论我尝试什么,该文件都是双字节unicode或ISO-8859-2(latin2)编码。
Glanebridge
答案 0 :(得分:2)
是的,但您需要Visual Studio 2005或更高版本。然后,您可以使用以下参数调用fopen:
LPCTSTR strText = "абв";
FILE *f = fopen(pszFilePath, "w,ccs=UTF-8");
_ftprintf(f, _T("%s"), (LPCTSTR) strText);
请记住,这是Microsoft扩展,它可能无法与gcc或其他编译器一起使用。
答案 1 :(得分:2)
如果您只想使用fprintf,则无需在文件上设置语言环境或设置任何特殊模式。您只需使用UTF-8编码的字符串。
#include <cstdio>
#include <codecvt>
int main() {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t> convert;
std::string utf8_string = convert.to_bytes(L"кошка 日本国");
if(FILE *f = fopen("tmp","w"))
fprintf(f,"%s\n",utf8_string.c_str());
}
将程序保存为带签名或UTF-16的UTF-8(即不使用UTF-8而不签名,否则VS将不会生成正确的字符串文字)。程序写入的文件将包含该字符串的UTF-8版本。或者你可以这样做:
int main() {
if(FILE *f = fopen("tmp","w"))
fprintf(f,"%s\n","кошка 日本国");
}
在这种情况下,您必须将文件保存为UTF-8 而不使用签名,因为您希望编译器认为源编码与执行编码相同...这有点像一个依赖于编译器,IMO,破坏行为的黑客。
对于将窄字符写入文件,您可以使用任何其他API执行基本相同的操作,但请注意,这些方法都不适用于将UTF-8写入Windows控制台。由于C运行时和/或控制台有点坏,您只能通过执行SetConsoleOutputCP(65001)然后使用puts
多种函数之一将UTF-8直接写入控制台。
如果要使用宽字符而不是窄字符,则可以使用基于语言环境的方法和文件描述符上的设置模式。
#include <cstdio>
#include <fcntl.h>
#include <io.h>
int main() {
if(FILE *f = fopen("tmp","w")) {
_setmode(_fileno(f), _O_U8TEXT);
fwprintf(f,L"%s\n",L"кошка 日本国");
}
}
#include <fstream>
#include <codecvt>
int main() {
if(auto f = std::wofstream("tmp")) {
f.imbue(std::locale(std::locale(),
new std::codecvt_utf8_utf16<wchar_t>)); // assumes wchar_t is UTF-16
f << L"кошка 日本国\n";
}
}
答案 2 :(得分:1)
理论上,您应该只设置一个使用UTF-8作为外部编码的语言环境。我的理解 - 我不是Windows程序员 - 是Windows has no such locale,因此您必须采用特定于实现的方法或非standard libraries(来自Dave评论的链接)。