使用迭代器将部分文件流读入字符串

时间:2010-11-03 11:47:33

标签: c++ string iterator

这是我到目前为止所尝试的但没有成功:

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之后它们指向同一个东西。

3 个答案:

答案 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; 
}