迭代器会导致ifstream.fail()被设置

我试图从文件中将大量数据导入到boost :: dynamic_bitset中。 为了达到这个目的,我希望使用一个与dynamic_bitset(uint32_t)的块大小相匹配的istream_iterator。

如下所示,我使用要导入的文件的位置设置我的ifstream。 但是,一旦我用ifstream初始化istream_iterator,就会设置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通常在错误涉及流的完整性丢失时设置,即使对流执行不同的操作,该错误也可能会持续存在。 badbit可以通过调用成员函数来独立检查。

编辑:

哈希包含160位散列,由单独的C应用程序中的SHA1实现生成。 这个文件中有几千个哈希。 我想读取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);

std::istream_iterator<T>T类型的对象使用输入operator>>() 。 也就是说,它假设格式化输入。 在构建时,它会尝试读取可能导致std::istream获取std::ios_base::failbit集合的第一个元素。


我认为初始化会从流中读取一个uint32_t。 类型uint32_t是无符号或无符号长整型的别名。 我有蠕变的感觉,你的文件不包含数字,但你期望(见例如ios_base :: binary openmode)一些打包,非文本表示被流读取。 如果是这样,你的期望就是错误的,但是如果不知道更多关于你的程序的内容,很难说清楚。 但请注意一点:如果您正在读取istream_iterator到最后,您将始终设置eofbit和failbit。 我想你只有失败位集,这表明解析错误。


问题是你有二进制数据。

istream_iteratoristreambuf_iterator使用operator>>来读取数据。 对于uint_32_t,这意味着它将读取人类可读的文本并将其转换为整数。 这对于二进制数据将会失败(大部分时间)。

你对速度有另一种误解。
一次读取4个字节不可能比每次读取1个字节更快(这会使代码更复杂,这可能会降低速度,但读取速度没有差别)。 这是因为从流中读取被缓冲。 一个巨大的块已经被读入一个缓冲区,当你进行一次读取时,它只是将它从一个位置复制到另一个位置。

你真正想做的是定义一个类,将数据作为一个单元复制到你的类中:

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

        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);
     }
};
链接地址: http://www.djcxy.com/p/61303.html

上一篇: iterator causes ifstream.fail() to be set

下一篇: safe reading from a stream in a for loop using getline