C++ 如何在C+中将文件编码格式设置为UTF8+;
我的软件要求包含导出数据的文件编码应为UTF8。但当我将数据写入文件时,编码总是ANSI。(我使用记事本++来检查这一点。) 我目前正在做的是通过读取文件、将其转换为UTF8并将文本写入新文件来手动转换文件C++ 如何在C+中将文件编码格式设置为UTF8+;,c++,winapi,utf-8,character-encoding,C++,Winapi,Utf 8,Character Encoding,我的软件要求包含导出数据的文件编码应为UTF8。但当我将数据写入文件时,编码总是ANSI。(我使用记事本++来检查这一点。) 我目前正在做的是通过读取文件、将其转换为UTF8并将文本写入新文件来手动转换文件 line是一个std::string inputFile是一个std::ifstream pOutputFile是一个文件* // ... if( inputFile.is_open() ) { while( inputFile.good() ) { get
line
是一个std::string
inputFile
是一个std::ifstream
pOutputFile
是一个文件*
// ...
if( inputFile.is_open() )
{
while( inputFile.good() )
{
getline(inputFile,line);
//1
DWORD dwCount = MultiByteToWideChar( CP_ACP, 0, line.c_str(), -1, NULL, 0 );
wchar_t *pwcharText;
pwcharText = new wchar_t[ dwCount];
//2
MultiByteToWideChar( CP_ACP, 0, line.c_str(), -1, pwcharText, dwCount );
//3
dwCount = WideCharToMultiByte( CP_UTF8, 0, pwcharText, -1, NULL, 0, NULL, NULL );
char *pText;
pText = new char[ dwCount ];
//4
WideCharToMultiByte( CP_UTF8, 0, pwcharText, -1, pText, dwCount, NULL, NULL );
fprintf(pOutputFile,pText);
fprintf(pOutputFile,"\n");
delete[] pwcharText;
delete[] pText;
}
}
// ...
不幸的是,编码仍然是ANSI。我搜索了一段时间寻找解决方案,但我总是通过MultiByteToWideChar和WideCharToMultiByte找到解决方案。然而,这似乎不起作用。我错过了什么
我也在这里寻找解决方案,但大多数UTF8问题都涉及C#和php内容。在VC++2010的Windows上,使用本地化方面std::codevt_UTF8_utf16(即在C++11中)是可能的(据我所知,尚未在GCC中实现)。中的示例代码包含读取/写入UTF-8文件所需的所有基本信息
std::wstring wFromFile = _T("AFAIK, fprintf()
does character conversions, so there is no guarantee that passing UTF-8 encoded data to it will actually write the UTF-8 to the file. Since you already converted the data yourself, use fwrite()
instead so you are writing the UTF-8 data as-is, eg:
DWORD dwCount = MultiByteToWideChar( CP_ACP, 0, line.c_str(), line.length(), NULL, 0 );
if (dwCount == 0) continue;
std::vector<WCHAR> utf16Text(dwCount);
MultiByteToWideChar( CP_ACP, 0, line.c_str(), line.length(), &utf16Text[0], dwCount );
dwCount = WideCharToMultiByte( CP_UTF8, 0, &utf16Text[0], utf16Text.size(), NULL, 0, NULL, NULL );
if (dwCount == 0) continue;
std::vector<CHAR> utf8Text(dwCount);
WideCharToMultiByte( CP_UTF8, 0, &utf16Text[0], utf16Text.size(), &utf8Text[0], dwCount, NULL, NULL );
fwrite(&utf8Text[0], sizeof(CHAR), dwCount, pOutputFile);
fprintf(pOutputFile, "\n");
std::wstring wFromFile=\u T(“AFAIK,fprintf()
进行字符转换,因此无法保证将UTF-8编码数据传递给它实际上会将UTF-8写入该文件。由于您自己已经转换了数据,因此请使用fwrite()
,这样您就可以按原样写入UTF-8数据,例如:
DWORD dwCount=MultiByteToWideChar(CP_ACP,0,line.c_str(),line.length(),NULL,0);
如果(dwCount==0)继续;
std::向量utf16Text(dwCount);
MultiByteToWideChar(CP_ACP,0,line.c_str(),line.length(),&utf16Text[0],dwCount);
dwCount=WideCharToMultiByte(CP_UTF8,0,&utf16Text[0],utf16Text.size(),NULL,0,NULL,NULL);
如果(dwCount==0)继续;
标准::矢量UTF8文本(dwCount);
WideChartMultiByte(CP_UTF8,0,&utf16Text[0],utf16Text.size(),&utf8Text[0],dwCount,NULL,NULL);
fwrite(&utf8Text[0]、sizeof(CHAR)、dwCount、poutput文件);
fprintf(pOutputFile,“\n”);
在Windows上,文件没有编码。每个应用程序都会根据自己的规则进行编码。你能做的最好的事情就是在文件前面放一个字母,希望它能被识别。类型char
没有任何编码的线索,它所能做的就是存储8位。因此,任何文本文件都只是一个字节序列和用户必须猜测底层编码。以BOM开头的文件表示UTF 8,但不再建议使用BOM。相比之下,Windows中的类型wchar\u t
始终解释为UTF 16
假设你有一个UTF8编码的文件,只有一行:“孔子说:微笑。孔子说:微笑!如果只向文件中写入英文字符,则记事本++在显示ansi时是正确的,并且该文件也将是UTF-8,因为其ansi/ascii编码中的所有英文字母都是UTF-8的有效子集。该文件将是一个CSV文件,包含英文字母、数字和一些特殊字符(“/”、“;”、“:”、“、”、“、“、”、“、”、“(“,”))。如果您没有任何字母或其他符号,那么不要担心。这是完整的ascii,因此自动生成utf-8。如果它都是纯ascii(因此也自动生成utf-8),您可能需要写入utf-8字节顺序标记(也称为BOM)我同意Alexey的观点,你的需求允许BOM还是禁止BOM?其次,你需要输出一些非英文字符来测试它。试试看金 = 汉字表示黄金,或俄文表示黄金,然后看看记事本++是怎么说的。