这是我到目前为止所尝试的但没有成功:
std::string ReadPartial( std::ifstream& _file, int _size )
{
std::istreambuf_iterator<char> first( _file );
std::istreambuf_iterator<char> last( _file );
std::advance( last, _size );
return std::string( first, last );
}
我知道如何阅读整个文件。
std::string Read( std::ifstream& _file )
{
std::istreambuf_iterator<char> first( _file );
std::istreambuf_iterator<char> last();
return std::string( first, last );
}
但这不是我想要做的。我收到一个空字符串。如果我在调试器中查看第一个也是最后一个,即使在std :: advance之后它们指向同一个东西。
答案 0 :(得分:5)
您是否有某些特殊原因需要使用迭代器?你可以一次读取字节:
std::string s(_size, '\0');
_file.read(&s[0], _size);
如果你真的想用迭代器阅读,你可以这样做:
std::string ReadPartial( std::ifstream& _file, int _size )
{
std::istreambuf_iterator<char> first( _file );
std::istreambuf_iterator<char> last;
std::string s;
s.reserve(_size);
while (_size-- && first != last) s += *first++;
return s;
}
答案 1 :(得分:5)
std::istreambuf_iterator<char> first( _file );
std::istreambuf_iterator<char> last( _file );
std::advance( last, _size );
istreambuf_iterators是输入迭代器。一旦你推进到最后,其他迭代器也会被修改。你将它们视为Forward Iterators,它具有你可以复制迭代器,推进它,然后通过推进副本获得相同序列的属性
对于一般情况:
template<class InIter, class Size, class OutIter>
void copy_n(InIter begin, InIter end, Size n, OutIter dest) {
for (; begin != end && n > 0; ++begin, --n) {
*dest++ = *begin;
}
}
//...
std::string ReadPartial(std::istream& file, int size) {
std::string result;
copy_n(istreambuf_iterator<char>(file), istreambuf_iterator<char>(),
size, back_inserter(result));
return result;
}
但是,在这种情况下,你最好调整字符串大小,最好使用istream :: read直接输入&amp; result [0],最后检查你是否读取了所需的字符数。
答案 2 :(得分:1)
此处没有可以帮助您的标准算法,但您可以使用此算法:
template< class InputIterator, class OutputIterator>
OutputIterator copy_n(InputIterator from,
size_t n,
OutputIterator to)
{
while (n)
{
*to = *from;
++from;
++to;
--n;
}
return to;
}
这可以与ReadPartial
一起使用,如下所示:
std::string ReadPartial( std::ifstream& _file, int _size )
{
std::istreambuf_iterator<char> first( _file );
std::string result;
copy_n(first, _size, std::back_inserter(result));
return result;
}