C++ / wcout / UTF-8
C++ / wcout / UTF-8
我正在读取一个 UTF-8 编码的 unicode 文本文件,并将其输出到控制台中,但显示的字符与我用于创建文件的文本编辑器中的字符不同。这是我的代码:
#define UNICODE
#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include "pugixml.hpp"
using std::ifstream;
using std::ios;
using std::string;
using std::wstring;
int main( int argc, char * argv[] )
{
ifstream oFile;
try
{
string sContent;
oFile.open ( "../config-sample.xml", ios::in );
if( oFile.is_open() )
{
wchar_t wsBuffer[128];
while( oFile.good() )
{
oFile >> sContent;
mbstowcs( wsBuffer, sContent.c_str(), sizeof( wsBuffer ) );
//wprintf( wsBuffer );// Same result as wcout.
wcout << wsBuffer;
}
Sleep(100000);
}
else
{
throw L"Failed to open file";
}
}
catch( const wchar_t * pwsMsg )
{
::MessageBox( NULL, pwsMsg, L"Error", MB_OK | MB_TOPMOST | MB_SETFOREGROUND );
}
if( oFile.is_open() )
{
oFile.close();
}
return 0;
}
一定有一些我不明白
问题是mbstowcs
实际上并不使用 UTF-8。它使用旧式的"多字节代码点",与 UTF-8 不兼容(尽管从技术上讲是可能的 [我相信] 定义 UTF-8 代码页,但在 Windows 中没有这样的东西)。
如果要将 UTF-8 转换为 UTF-16,可以使用 MultiByteToWideChar
,codepage
为 CP_UTF8
。
宽字符串并不意味着 UTF-8。事实上,情况恰恰相反:UTF-8 表示 Unicode 转换格式(8 位);这是一种在 8 位字符上表示 Unicode 的方法,因此您的正常char
s。您应该将其读入普通字符串(而不是宽字符串)。
宽字符串使用wchar_t
,在Windows上是16位。操作系统使用 UTF-16 实现其"广泛"功能。
在 Windows 上,可以使用 MultiByteToWideChar
将 UTF-8 字符串转换为 UTF-16
我制作了一个C++ char_t
容器,最多可容纳 6 个 8 位char_t将其存储在std::vector
中。将其与wchar_t
相互转换或追加到std::string
。
在这里查看:在 Github 上查看 UTF-8_String 结构
#include "UTF-8_String.h" //header from github link above
iBS::u8str raw_v;
iBS::readu8file("TestUTF-8File.txt",raw_v);
std::cout<<raw_v.str()<<std::endl;
这是将wchar_t转换为上面标题中 u8char 结构中的uint32_t的函数。
#include <cwchar>
u8char& operator=(wchar_t& wc)
{
char temp[6];
std::mbstate_t state ;
int ret = std::wcrtomb((&temp[0]), wc, &state);
ref.resize(ret);
for (short i=0; i<ret; ++i)
ref[i]=temp[i];
return *this;
};
我发现wifstream
工作得很好,即使在Visual Studio调试器中也能正确显示UTF-8单词(我正在阅读繁体中文单词),来自这篇文章:
#include <sstream>
#include <fstream>
#include <codecvt>
std::wstring readFile(const char* filename)
{
std::wifstream wif(filename);
wif.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>));
std::wstringstream wss;
wss << wif.rdbuf();
return wss.str();
}
// usage
std::wstring wstr2;
wstr2 = readFile("C:\yourUtf8File.txt");
wcout << wstr2;
- HEX值到wchar_t字符(UTF-8)的转换
- 带有Protobuf序列化的C++Hazelcast:字符串不是UTF-8格式的
- 转换特殊字符(UTF-8)
- 如何在CPP的给定目录中列出UTF编码的文件名?
- 如何使用 C++将 ISO-2022-KR 编码转换为 UTF-8 编码?
- 在C++中使用 UTF-8 字符串和字符
- 如何将 UTF-8 文本从文件转换为某个可以迭代的容器,并检查每个符号是否为C++字母数字?
- 将C++ std::string 转换为 UTF-16-LE 编码的字符串
- 在基于英语的系统上将 UTF-8 路径转换为宽字符会引发异常
- C++ 将 UTF-8 转换为字符串
- 从/到 UTF-8/UTF-16 的转换需要(例如:utf8 -> 代码点,然后代码点到 utf16)或(例如:utf8 -> utf16)?
- 通过分隔符分隔包含 UTF-16 BE 文本的uint8_t数组
- 一种从内存中删除 UTF 字节的方法?
- "C.UTF-8" C++ Windows 上的语言环境?
- 无法将字符数组转换为包含 utf-8 字符的字符串
- 从 UTF-8 字节数组创建字符串?
- 如何在C++中使用 UTF-8 和 Unicode?C++20 char8_t有多大?
- PostgreSQL C++ libpq 编码 UTF-8 问题
- 如何C++ WCOUT UTF-16 编码的字符数组?
- C++ / wcout / UTF-8