искать и проникать в wifstream работать неправильно

У меня есть файл, как показано ниже:

$ 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

Кто-нибудь имеет представление, что является причиной, почему вышеуказанные проблемы возникают с этим файлом?

1

Решение

Проблема в том, как вы звоните seekg функция. Когда вы вызываете его с одним аргументом, он используется как абсолютная позиция с начала, и вы будете стремиться к любой ценности std::ios::end есть, что бывает 2 в твоем случае.

Вместо этого вы должны использовать перегрузку с двумя аргументами:

wss.seekg(0, std::ios_base::end);  // Seek to offset 0 from the end

У вас по-прежнему будут проблемы с чтением файла с использованием широких символов, так как его содержимое, похоже, не таково. UTF-8 является многобайтовым узкий кодировка символов.

1

Другие решения

Я обнаружил, что у кого-то были похожие проблемы с getline:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15733

0

По вопросам рекламы [email protected]