C ++:缓冲cin istream

时间:2017-11-11 08:07:22

标签: c++ input file-io io

问题是:

我有一个代码可以在功能齐全的const mongoose = require('mongoose'); const Schema = mongoose.Schema; const Post = require('./articles'); const CommentSchema = new Schema({ comment: String, articleId: String }, { timestamps: true }); const Comments = mongoose.model('Comments', CommentSchema); module.exports = Comments;上运行。它使用如下方法:

istream

这些方法仅适用于来自文件的istream。但是,如果我以这种方式使用istream is; is.seekg(...) // <--- going backwards at times is.tellg() // <--- to save the position before looking forward etc. ,它将无效 - cin无法选择保存位置,向前读取,然后返回到保存位置。

cin

我可以将// So, I can't cat the file into the program cat file | ./program // I can only read the file from inside the program ./program -f input.txt // Which is the problem with a very, very large zipped file // ... that cannot coexist on the same raid-10 drive system // ... with the resulting output zcat really_big_file.zip | ./program //<--- Doesn't work due to cin problem ./program -f really_big_file.zip //<--- not possible without unzipping 读入cin,然后处理deque。 1mb deque缓冲区就足够了。然而,这在三个方面存在问题:

  1. 我必须使用deque
  2. 重写所有内容
  3. 它不像使用deque一样具有防弹性,代码已经调试过了
  4. 好像,如果我把它作为一个istream实现有些困难的话,有人会过来说,你为什么不这样做___
  5. 创建可用的deque对象的正确/最有效的方法是什么?在所有成员都处于活动状态的情况下,使用istream cin

    (记住表现很重要)

2 个答案:

答案 0 :(得分:0)

cin是用户输入,应视为不可预测。如果你想使用上面提到的功能,并且你确定你的输入,你可以读取istringstream的整个输入,然后对它进行操作

答案 1 :(得分:0)

您可以在获取新数据时创建从std::cin读取的过滤流缓冲区,但缓冲所有收到的字符。您可以在缓冲的输入范围内实现搜索。在已经缓冲的输入结束之后寻找将意味着读取相应数量的数据。以下是相应实现的示例:

#include <iostream>
#include <vector>

class bufferbuf
    : public std::streambuf {
private:
    std::streambuf*   d_sbuf;
    std::vector<char> d_buffer;

    int_type underflow() {
        char buffer[1024];
        std::streamsize size = this->d_sbuf->sgetn(buffer, sizeof(buffer));
        if (size == 0) {
            return std::char_traits<char>::eof();
        }
        this->d_buffer.insert(this->d_buffer.end(), buffer, buffer + size);
        this->setg(this->d_buffer.data(),
                   this->d_buffer.data() + this->d_buffer.size() - size,
                   this->d_buffer.data() + this->d_buffer.size());
        return std::char_traits<char>::to_int_type(*this->gptr());
    }
    pos_type seekoff(off_type off, std::ios_base::seekdir whence, std::ios_base::openmode) {
        switch (whence) {
        case std::ios_base::beg:
            this->setg(this->eback(), this->eback() + off, this->egptr());
            break;
        case std::ios_base::cur:
            this->setg(this->eback(), this->gptr() + off, this->egptr());
            break;
        case std::ios_base::end:
            this->setg(this->eback(), this->egptr() + off, this->egptr());
            break;
        default: return pos_type(off_type(-1)); break;
        }
        return pos_type(off_type(this->gptr() - this->eback()));
    }
    pos_type seekpos(pos_type pos, std::ios_base::openmode) {
        this->setg(this->eback(), this->eback() + pos, this->egptr());
        return pos_type(off_type(this->gptr() - this->eback()));
    }
public:
    bufferbuf(std::streambuf* sbuf)
        : d_sbuf(sbuf)
        , d_buffer() {
        this->setg(0, 0, 0); // actually the default setting
    }
};

int main() {
    bufferbuf      sbuf(std::cin.rdbuf());
    std::istream   in(&sbuf);
    std::streampos pos(in.tellg());

    std::string line;
    while (std::getline(in, line)) {
        std::cout << "pass1: '" << line << "'\n";
    }
    in.clear();
    in.seekg(pos);
    while (std::getline(in, line)) {
        std::cout << "pass2: '" << line << "'\n";
    }
}

此实现在将输入传递到读取步骤之前缓冲输入。您可以阅读单个字符(例如,将char buffer[1024];更改为char buffer[1];或使用sgetn()来适当地替换sbumpc()的使用,以提供更直接的响应:有一个交易 - 在即时响应和批处理性能之间取消。