Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

copy_n or until eof?

How would I do this using STL algorithms?

std::ifstream file(filename);

std::vector<unsigned char> buf;
for(auto file_it = std::istreambuf_iterator<char>(file); file_it != std::istreambuf_iterator<char>() && buf.size() < 2048; ++file_it)
    buf.push_back(*file_it);

Note buf.size() < 2048.

e.g. what will happen if I do the following, and the file is smaller than 2048 bytes?

std::copy_n(std::istreambuf_iterator<char>(file), 2048, std::back_inserter(buf));
like image 939
ronag Avatar asked Dec 04 '11 23:12

ronag


1 Answers

Like the documentation says, std::copy_n() will copy exactly n items. It will keep reading past the end of the sequence the iterator refers to. I'm not sure what the standard says about istreambuf_iterator<>, though. It's probably undefined behavior, but streams are likely to produce lots of copies of eof() past the end. This might lead to lots of garbage when there are less than 2048 bytes available.

In any case, if you want to reliably copy up to n items, you'll need to write your own function:

template<typename I1, typename I2, typename size_type>
I copy_upto_n ( I1 begin, I1 end, size_type n, I2 out )
{
    for (size_type i=0; (i < n) && (begin != end); ++i)
    {
        *out++ = *begin++;
    }
    return out;
}

Some people might use std::iterator_traits<> instead of an extra template parameter to force the same distance type as the iterator.

like image 142
André Caron Avatar answered Oct 31 '22 18:10

André Caron