我有一个如下文件:
$ xxd 1line
0000000: 3939 ba2f 6f20 6f66 0d0a 99./o of..
我想在C ++中阅读这一行:
#include <codecvt>
#include <iostream>
#include <locale>
#include <fstream>
#include <string>
int main(int argc, char** argv) {
std::wifstream wss(argv[1], std::ios::binary);
wss.seekg(std::ios_base::end);
const auto fileSize = wss.tellg();
wss.seekg(std::ios_base::beg);
// std::locale utf8_locale(wss.getloc(), new std::codecvt_utf8<wchar_t, 0x10FFFF, std::consume_header>);
// wss.imbue(utf8_locale);
std::wstring wline;
std::getline(wss, wline);
std::cout << "filelen: " << fileSize << std::endl;
std::cout << "strlen: " << wline.size() << std::endl;
std::wcout << "str: " << wline << std::endl;
return 0;
}
我用下面的方式编译它:
$ g++ -std=c++11 imbue_issue.cpp
第一件事:似乎wss.seekg(std :: ios_base :: end)不会在文件末尾移动文件位置:
$ ./a.out 1line
filelen: 2
strlen: 9
str: 99?/o of
第二件事是,当取消注释与语言环境相关的行时,getline仅读取2个字符:
$ ./a.out 1line
filelen: 2
strlen: 2
str: 99
我的编译器:
$ g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/c++/4.2.1
Apple LLVM version 7.3.0 (clang-703.0.31)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
有谁知道这个文件出现上述问题的原因是什么?
问题是如何调用该seekg
函数。当您使用一个参数调用它时,它从一开始就被用作绝对位置,您将寻求具有任何值的值std::ios::end
,这恰好2
在您的情况下。
相反,您应该使用两个参数的重载:
wss.seekg(0, std::ios_base::end); // Seek to offset 0 from the end
您仍然会遇到使用宽字符类型读取文件的问题,因为内容似乎并非如此。UTF-8是一种多字节的窄字符编码。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句