如何使文件流以 UTF-8 C++读取
How to make a filestream read in UTF-8 C++
我能够通过重定向终端上的输入和输出,然后使用 wcin 和 wcout 成功读取 UTF8 字符文本文件
_setmode(_fileno(stdout), _O_U8TEXT);
_setmode(_fileno(stdin), _O_U8TEXT);
现在我希望能够使用文件流读取 UTF8 文本,但我不知道如何设置文件流的模式,以便它可以像我使用 stdin 和 stdout 一样读取这些字符。我尝试使用wifstreams/wofstreams,那些仍然自己读取和写入垃圾的人。
C++的<iostreams>
库没有内置支持从一种文本编码到另一种文本编码的转换。如果需要将输入文本从 utf-8 转换为另一种格式(例如,编码的基础代码点(,则需要手动编写该转换。
std::string data;
std::ifstream in("utf8.txt");
in.seekg(0, std::ios::end);
auto size = in.tellg();
in.seekg(0, std::ios::beg);
data.resize(size);
in.read(data.data(), size);
//data now contains the entire contents of the file
uint32_t partial_codepoint = 0;
unsigned num_of_bytes = 0;
std::vector<uint32_t> codepoints;
for(char c : data) {
uint8_t byte = uint8_t(c);
if(byte < 128) {
//Character is just a basic ascii character, so we'll just set that as the codepoint value
codepoints.push_back(byte);
if(num_of_bytes > 0) {
//Data was malformed: error handling?
//Codepoint abruptly ended
}
} else {
//Character is part of multi-byte encoding
if(partial_codepoint) {
//We've already begun storing the codepoint
if((byte >> 6) != 0b10) {
//Data was malformed: error handling?
//Codepoint abruptly ended
}
partial_codepoint = (partial_codepoint << 6) | (0b0011'1111 & byte);
num_of_bytes--;
if(num_of_bytes == 0) {
codepoints.emplace_back(partial_codepoint);
partial_codepoint = 0;
}
} else {
//Beginning of new codepoint
if((byte >> 6) == 0b10) {
//Data was malformed: error handling?
//Codepoint did not have proper beginning
}
while(byte & 0b1000'0000) {
num_of_bytes++;
byte = byte << 1;
}
partial_codepoint = byte >> num_of_bytes;
}
}
}
此代码将可靠地从 [正确编码] utf-8 转换为 utf-32,这通常是直接转换为字形 + 字符的最简单形式,但请记住,代码点不是字符。
为了保持代码中的一致性,我的建议是使用std::string
将 utf-8 编码的文本存储在您的程序中,并将 utf-32 编码的文本存储为std::vector<uint32_t>
。
相关文章:
- 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 问题
- QTcpServer/QTcpSocket:使用 QDataStream 与直接发送 UTF-8 数据
- 在 node.js 中将缓冲区从 C++ 转换为 UTF-8 字符串