如何将fstream中的128个字节精确读入字符串对象?
我写了一些代码来读取文件的前128个字节然后打印它然后打印文件的最后128个字节并打印出来。最后一部分可以工作,因为您可以轻松地迭代到EOF,但是如何从前面获得正好128个字节?下面的代码不起作用,因为你不能将128添加到ifstream迭代器,它不可索引,只能递增(似乎)。
当然我可以制作一个迭代器和* ++它128次,但必须有一条直线的方法来做,对吧?
#include <iostream>
#include <fstream>
#include <string>
int main(int argc, char **argv)
{
std::ifstream ifs ("input.txt",std::ifstream::in | std::ifstream::binary);
if (ifs.good())
{
// read first 128 bytes into a string
ifs.seekg(0,std::ifstream::beg);
std::string first128((std::istreambuf_iterator<char>(ifs)),
(std::istreambuf_iterator<char>(ifs))+128);
std::cout << first128 << std::endl;
// read last 128 bytes into a string
ifs.seekg(-128,std::ifstream::end);
std::string last128((std::istreambuf_iterator<char>(ifs)),
std::istreambuf_iterator<char>());
std::cout << last128 << std::endl;
return 0;
}
return 1;
}
答案 0 :(得分:1)
char buffer[129];
ifs.read (buffer,128);
buffer[128] = '\0';
first128 = buffer;
那么:
template <typename Itr, typename Out>
void copy_n(Itr it, size_t count, Out out)
{
for(size_t i=0;i<count;++i)
out = *it++;
}
...
std::string first128;
std::istreambuf_iterator<char> it(ifs);
copy_n( it, 128,
std::back_inserter<std::string>(first128) );
答案 1 :(得分:1)
我的回答使用了一个中间缓冲区,但也许你会很高兴它使用迭代器从缓冲区初始化字符串。
std::vector<char> buffer(128); // create a buffer
ifs.read( &buffer[0], buffer.size() ); // read to buffer
std::string first128( buffer.begin(), buffer.end() ); // copy from vector
对我来说,似乎他们对iostreams的实现有点太可爱了。尝试使用迭代器进行流I / O非常复杂。
顺便说一句,我怀疑你正在尝试的实现将在各种中间缓冲(可能是内核中的一些,库中的一些)以及重新分配和复制字符串几个它的成长时间。
另一个想法:你真的需要标准字符串中的结果吗?您可能只是从向量开始工作 - 避免复制到字符串的最后一步。或者,如果您有冒险精神,可以创建自己的字符串类, 允许您以与向量相同的方式公开内部缓冲区。
答案 2 :(得分:0)
这里我有一些关于streambuffer的研究,通过构造函数从istream直接读取字符串:
class mystringbuf : public std::stringbuf
{
public:
explicit mystringbuf(std::istream& istr, size_t n,
std::ios_base::openmode __mode = std::ios_base::in )
{
_M_string.resize(n);
std::stringbuf::_M_stringbuf_init(__mode);
istr.read(gptr(), n);
}
public:
std::stringbuf::char_type* gptr() const
{
return std::stringbuf::gptr();
}
std::string& str_ref(){
return _M_string;
}
};
std::ostream& operator << (std::ostream& ostr, mystringbuf& buf){
ostr << buf.str_ref();
return ostr;
}
使用示例:
using std::cout;
using std::endl;
int main()
{
std::stringbuf buffer; // empty buffer
buffer.str("abc def ABC DEF "); // not empty now
std::istream is (&buffer); // associate stream buffer to stream
mystringbuf data(is, 10); // read 10 bytes
cout << "data=" << data << endl;
return 0;
}
输出:
data=abc def AB
如果我错在某处,请转发我。