C++ 为什么我不能读取长度超过4094个字符的UTF-16文件?
一些信息:C++ 为什么我不能读取长度超过4094个字符的UTF-16文件?,c++,linux,utf-16,wstring,wifstream,C++,Linux,Utf 16,Wstring,Wifstream,一些信息: #include <iostream> #include <fstream> #include <locale> #include <codecvt> void createTestFile() { std::ofstream file ("utf16le.txt", std::ofstream::binary); if (file.is_open()) { uint16_t bom = 0xFEFF; // UTF-
#include <iostream>
#include <fstream>
#include <locale>
#include <codecvt>
void createTestFile() {
std::ofstream file ("utf16le.txt", std::ofstream::binary);
if (file.is_open()) {
uint16_t bom = 0xFEFF; // UTF-16 little endian BOM
uint64_t abcd = 0x0064006300620061; // UTF-16 "abcd" string
file.write((char*)&bom,2);
for (size_t i=0; i<2000; i++) {
file.write((char*)&abcd,8);
}
file.close();
}
}
int main() {
//createTestFile(); // uncomment to make the test file
std::wifstream file;
std::wstring line;
file.open("utf16le.txt");
file.imbue(std::locale(file.getloc(), new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>));
if (file.is_open()) {
while (getline(file,line)) {
std::wcout << line << std::endl;
}
}
}
- 我只在Linux上试过这个
- 我用GCC(7.2.0)和Clang(3.8.1)都试过了
- 据我所知,它需要C++11或更高版本
#include <iostream>
#include <fstream>
#include <locale>
#include <codecvt>
void createTestFile() {
std::ofstream file ("utf16le.txt", std::ofstream::binary);
if (file.is_open()) {
uint16_t bom = 0xFEFF; // UTF-16 little endian BOM
uint64_t abcd = 0x0064006300620061; // UTF-16 "abcd" string
file.write((char*)&bom,2);
for (size_t i=0; i<2000; i++) {
file.write((char*)&abcd,8);
}
file.close();
}
}
int main() {
//createTestFile(); // uncomment to make the test file
std::wifstream file;
std::wstring line;
file.open("utf16le.txt");
file.imbue(std::locale(file.getloc(), new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>));
if (file.is_open()) {
while (getline(file,line)) {
std::wcout << line << std::endl;
}
}
}
#包括
#包括
#包括
#包括
void createTestFile(){
std::ofstream文件(“utf16le.txt”,std::ofstream::binary);
if(file.is_open()){
uint16_t bom=0xFEFF;//UTF-16小端元bom
uint64_t abcd=0x0064006300620061;//UTF-16“abcd”字符串
写入((char*)&bom,2);
对于(size_t i=0;i而言,这看起来像是一个库错误。使用gdb
逐步浏览gcc 7.1.1编译的示例程序:
(gdb) n
28 while (getline(file,line)) {
(gdb) n
29 std::wcout << line << std::endl;
(gdb) p line.size()
$1 = 8000
(gdb)n
28 while(getline(文件,行)){
(gdb)n
29 std::wcout这个例子对我来说效果很好。我得到一个有2000次“abcd”的文件并且它正确显示。在Visual Studio 2015中试用过。您如何验证该文件?也许您的查看器有错误?感谢您的回答!我很高兴它在Windows上正常工作,没有任何更改,如果可以的话,我希望保持跨平台兼容。那么我想该错误一定与Linux有关。甚至可能是som像我使用的终端一样愚蠢…?在使用调试器设置断点并检查读取字符串的内容后,使用gcc 7.1.1复制,所有迹象都指向libstdc++错误。读取字符串的宽度为8000个字符,正如预期的那样。但从行[4094]开始
,endianness被粗暴地颠倒了。您应该打开一个gcc错误,并附加调试器的输出,显示行[4093]
和行[4094]中的内容这是一个完美的学习机会。知道如何有效地使用调试器是每个C++开发者所需的技能。你的第一个项目是复制我的结果。由于缺少注释中的断线,这将被StActOfFultFug所破坏,但是:<代码>(GDB)p行(4093)$ 19 =(α-GuuuxCx::Y-AlalOrthGosith::ValueSyType)。@0x628244:98 L'b'(gdb)p行[4094]$20=(\uuu gnu\u cxx::\uu alloc\u traits::value\u type&)@0x628248:25344 L'挀'代码>——C++库显然是在读取这个字符串。