iterator causes ifstream.fail() to be set

I'm attempting to import a large amount of data from a file into a boost::dynamic_bitset. To accomplish this, I was hoping to use an istream_iterator which matches the block size of the dynamic_bitset (uint32_t).

As shown below, I setup my ifstream using the location of the file to be imported. However, once I initialize the istream_iterator with the ifstream, the ifstream's fail bit is set.

Any advice regarding why this is occurring?

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;

According to cplusplus.com :

failbit is generally set by an input operation when the error was related to the internal logic of the operation itself, so other operations on the stream may be possible. While badbit is generally set when the error involves the loss of integrity of the stream, which is likely to persist even if a different operation is performed on the stream. badbit can be checked independently by calling member function bad.

Edit:

The hash contains 160 bit hashes, produced by a SHA1 implementation in a separate C application. There are a few thousand hashes in this file. I would like to read 5 blocks of 4 bytes, instead of 20 blocks of 1 byte (hence my use of uint32_t as the block size) I've pulled in the relevant code from the C application, which shows the hashes being produced and then written to a file:

#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);

The std::istream_iterator<T> use the input operator>>() for objects of type T . That is, it assumes formatted input. Upon construction it tries to read the first element which may cause the std::istream to get std::ios_base::failbit set.


I think the initialization will read a uint32_t from the stream. The type uint32_t is an alias for either unsigned or or unsigned long. I have the creeping feeling that your file doesn't contain numbers but that you expect (see eg the ios_base::binary openmode) some packed, non-text representation to be read by the stream. If this is the case, your expectation is simply wrong, but it's hard to tell without knowing more about your program. One note though: If you're reading the istream_iterator to the end, you will always have both eofbit and failbit set. I guess you only have failbit set, which suggests a parsing error.


The problem is you have binary data.

The istream_iterator and istreambuf_iterator use operator>> to read data. For uint_32_t this means it will read human readable text and convert it into an integer. This will fail (most of the time) for binary data.

You have another misconception about speed.
Reading 4 bytes at a time is unlikely to be any faster than reading 1 bytes at a time (it will make the code more complex which may slow it down but there will be no difference in reading speed). This is because reading from the stream is buffered. A huge chunk has already been read into a buffer when you do a read it is simply copying it from one location to another.

What you really want to do is define a class an copy the data as a single unit into your class:

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/61304.html

上一篇: 如何使C ++ endl操作器线程安全?

下一篇: 迭代器会导致ifstream.fail()被设置