Инициализация istream_iterator приводит к установке ifstream.fail ()

Я пытаюсь импортировать большой объем данных из файла в boost :: dynamic_bitset. Для этого я надеялся использовать istream_iterator, который соответствует размеру блока dynamic_bitset (uint32_t).

Как показано ниже, я устанавливаю свой ifstream, используя местоположение импортируемого файла. Однако, как только я инициализирую istream_iterator с помощью ifstream, устанавливается бит сбоя ifstream.

Любой совет относительно того, почему это происходит?

ifstream memHashes (hashFileLocation, ios::in | ios::binary);
if(memHashes.is_open() == false || memHashes.good() == false) { break; }
std::istream_iterator<uint32_t> memHashesIt(memHashes);
std::istream_iterator<uint32_t> memHashesEOFIt;

По данным cplusplus.com:

failbit обычно устанавливается операцией ввода, когда ошибка была
связаны с внутренней логикой самой операции, поэтому другие
операции на потоке могут быть возможны. Хотя бадбит это вообще
устанавливается, когда ошибка связана с потерей целостности потока, что
может сохраняться, даже если на
поток. Badbit можно проверить независимо, вызвав функцию-член
плохой.

Редактировать:

Хэш содержит 160-битные хэши, созданные реализацией SHA1 в отдельном C-приложении. В этом файле несколько тысяч хэшей. Я хотел бы прочитать 5 блоков по 4 байта вместо 20 блоков по 1 байту (отсюда мое использование uint32_t в качестве размера блока). Я извлек соответствующий код из приложения C, который показывает производимые хеши, а затем записано в файл:

#define HASH_SIZE 20 // 160 bits / 8 bits per byte = 20 bytes

FILE *fp;
fp = fopen(hash_filename, "wb");
if (!fp) {
MSG("Hash dump file cannot be opened");
fclose(fp);
return NULL;
}

uint8_t *p;
unsigned char hash[HASH_SIZE];
SHA1((unsigned char*)p, LENGTH_TO_HASH, hash);
fwrite(hash, HASH_SIZE, 1, fp);

2

Решение

std::istream_iterator<T> использовать вход operator>>() для объектов типа T, То есть он предполагает форматированный ввод. При построении он пытается прочитать первый элемент, который может вызвать std::istream получить std::ios_base::failbit задавать.

2

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

Я думаю, что инициализация будет читать uint32_t из потока. Тип uint32_t является псевдонимом для unsigned или unsigned long. У меня такое ощущение, что ваш файл не содержит чисел, но вы ожидаете (см., Например, ios_base :: binary openmode) некоторое упакованное нетекстовое представление, которое будет прочитано потоком. Если это так, то ваши ожидания просто неверны, но трудно сказать, не зная больше о вашей программе. Одно замечание: если вы читаете istream_iterator до конца, у вас всегда будут установлены как eofbit, так и failbit. Я предполагаю, что у вас есть только набор битов сбоя, который предлагает ошибку синтаксического анализа.

0

Проблема в том, что у вас есть двоичные данные.

istream_iterator а также istreambuf_iterator использование operator>> читать данные. Для uint_32_t это означает, что он будет читать текст, читаемый человеком, и преобразовывать его в целое число. Это не удастся (большую часть времени) для двоичных данных.

У вас есть другое представление о скорости.
Чтение 4 байтов за раз вряд ли будет быстрее, чем чтение 1 байта за раз (это сделает код более сложным, что может замедлить его, но не будет никакой разницы в скорости чтения). Это потому, что чтение из потока буферизовано. Огромный кусок уже был считан в буфер, когда вы выполняете чтение, он просто копирует его из одного места в другое.

Что вы действительно хотите сделать, это определить класс, скопировать данные как единое целое в ваш класс:

class ShaMine
{
std::vector<char>  data;
public:
ShaMine(): data(20, '\0') {}

friend std::istream& operator>>(std::istream& s, ShaMine& dst)
{
return s.read(&data[0], 20);
}

void poop(std::ostream& s)
{
s << "Hi there: Char 0 is :" << (int) data[0] << "\n";
}
};

int main()
{
std::ifstream   sfile("FILE");

for(std::istream_iterator<ShaMine> loop(sfile); loop != std::istream_iterator<ShaMine>(); ++lop)
{
loop->poop(std::cout);
}
};
0
По вопросам рекламы [email protected]