在cpp中的istream前插入一个字符串

时间:2018-03-20 23:07:48

标签: c++ istream boost-iostreams

我的问题是我想在iostream前添加一些字符串。你可以在std :: cin前面说。

#include <iostream>
#include <string>

void print(std::istream & in){// function not to be modified
    std::string str;
    in >> str;
    std::cout<< str << std::endl;
    in >> str;
    std::cout<< str << std::endl;
}

int main() {
    std::string header = "hello ";
    //boost::iostream::filtering_istream in(std::cin);
    std::istream & in = std::cin;

    //you may do someting here
    //something like inserting characters into cin or something with buffers

    print(in);
}

我想要实现功能,如果我提供像

这样的输入
$ cat file.txt
help me to solve this.
$
$ ./a.out < file
hello
help
$

欢迎任何形式的帮助。你可以使用boost :: iostream来实现它。

2 个答案:

答案 0 :(得分:3)

流不是容器。这是一个数据流。您无法更改已经浮动的数据。唯一的例外是绑定到块设备的流,您可以在其中寻找,例如fstream - 但即便如此,你也只能覆盖。

相反,构建代码以便在查询流之前消耗header

答案 1 :(得分:0)

你应该避免这个问题。如果不是同一个流,请不要从同一个流中解析所有内容。

低技术

低技术解决方案&#34;是将流复制到字符串流,将你的&#34;前缀&#34;首先在缓冲区中:

<强> Live On Coliru

// It works
IdOnly<Long> findFirstBy();

// It works too (although it does not limit the query in database)
Entity findOne(Example<Entity> example);

// It doesn't work. Throws an ClassCastException when returns a non-null entity
IdOnly<Long> findOne(Example<Entity> example);

// That's the one I really need
// The server doesn't start (IndexOutOfBoundsException)
IdOnly<Long> findFirstBy(Example<Entity> example);

给定输入#include <iostream> #include <string> #include <sstream> void print(std::istream &in) { // function not to be modified std::string str; while (in >> str) std::cout << str << std::endl; } int main() { std::string header = "hello "; std::stringstream in; in << header << std::cin.rdbuf(); print(in); } 打印:

foo bar qux

高科技

您始终可以创建实现所需行为的自定义流缓冲区:

<强> Live On Coliru

hello
foo
bar
qux

还打印

#include <iostream>
#include <sstream>
#include <vector>

template <typename B1, typename B2>
class cat_streambuf : public std::streambuf {
    B1* _sb1;
    B2* _sb2;
    std::vector<char> _buf;
    bool _insb1 = true;

  public:
    cat_streambuf(B1* sb1, B2* sb2) : _sb1(sb1), _sb2(sb2), _buf(1024) {}

    int underflow() {
        if (gptr() == egptr()) {
            auto size = [this] {
                if (_insb1) {
                    if (auto size = _sb1->sgetn(_buf.data(), _buf.size()))
                        return size;
                    _insb1 = false;
                }

                return _sb2->sgetn(_buf.data(), _buf.size());
            }();

            setg(_buf.data(), _buf.data(), _buf.data() + size);
        }
        return gptr() == egptr() 
            ? std::char_traits<char>::eof()
            : std::char_traits<char>::to_int_type(*gptr());
    }
};

void print(std::istream &in) { // function not to be modified
    std::string str;
    while (in >> str)
        std::cout << str << std::endl;
}

int main() {
    std::stringbuf header("hello ");
    cat_streambuf both(&header, std::cin.rdbuf());

    std::istream is(&both);
    print(is);
}

输入相同的内容。对于(非常)大流,这肯定会更好地扩展。