我想将std :: istream中固定长度的数据复制到字符串中:
std::istream & operator >> ( std::istream & is, LogMsg & msg )
{
// read in 4 bytes - a uint32_t that describes the number of bytes in message:
// next, read the message bytes into the LogMsg
typedef std::istream_iterator<unsigned char> Iter;
Iter i (is);
uint32_t nSize = 0;
std::string & sMsg = msg.MsgRef();
is >> nSize;
sMsg.reserve(nSize);
std::copy(
i.begin(), i.begin() + nSize,
std::back_inserter(sMsg)
);
return is;
}
我不能使用这个解决方案,因为迭代器上的std :: istream_iterator :: begin()函数只是c ++ 11(我被约束为-std = gnu ++ 0x with gcc 4.4.7
那么,如何将输入流中固定长度的数据复制到字符串中呢?
我最初喜欢std :: istream :: read,这似乎很合适 - 它有以下语法
is.read (buffer,length);
但我不认为你可以读入字符串的内部缓冲区,我想避免复制到临时缓冲区。我可以用某种方式使用streambuf吗?
答案 0 :(得分:3)
您可以复制到字符串的内部缓冲区,只需确保它的大小合适:
sMsg.resize(nSize);
is.read(&sMsg[0], nSize);
它的效率低于使用begin()
的解决方案,因为您必须对要立即覆盖的大量数据进行零初始化。但它将在C ++之前的11版本中运行。
答案 1 :(得分:3)
使用std::copy_n()
:
std::copy_n(i, nSize, std::back_inserter(sMsg));
答案 2 :(得分:3)
明显的解决方案是std::copy_n
:
std::copy_n( std::istreambuf_iterator<char>( is ), size, std::back_inserter( msg ) );
这只有在你可以确定字符在那里时才有效, 然而。如果您在尝试阅读时遇到文件结尾 字符,未定义的行为随之而来。这意味着尽管如此 一个明显的解决方案,它可能不是一个好的解决方案。
然而,在C ++ 11中,正式地,在早期的实现中,在 练习,你可以读入内部缓冲区。你必须确定 该字符串有足够的空间:
msg.resize( size );
is.read( &msg[0], msg.size() );
(由于某种原因,没有非const版本的
std::string::data()
,尽管保证了潜在的连续性
C ++ 11)