C/C++如何在回车后从stdin中读取,连续命中两次或在两个换行后

C/C++ How to read from stdin after enter is hit twice in a row or after 2 newlines

本文关键字:两次 换行 两个 读取 C++ 回车 stdin 连续      更新时间:2023-10-16

我正试图让用户向控制台输入一块文本,只有在连续两次点击回车后,或者用另一种方式,当在已经为空的行上点击回车时,我的程序才会从stdin读取该文本。但是,我想继续从stdin读取,所以基本上,只有在已经为空的行上点击回车时才从stdin中读取。然后冲洗并重新启动。

用户输入示例:

Hello(n)
World(n)
(n)
(Read Now)

我一直找不到能够指定这种行为的输入函数。

此外,我尝试了一些使用单个字符检索功能的方法,但我一直无法使其正常工作。

有人知道优雅地做这件事的方法吗?

实施的答案:

char word[100];
int i = 0;
while ((word[i++] = getchar())!='n' || (word[i++]=getchar())!='n');
printf("%s",word);

显然,在使用之前需要处理缓冲区溢出问题。只是一个例子。

基本上,您希望忽略输入,直到序列nn。你可以用

while (getchar()!='n' || getchar()!='n');
//read the input now

忽略所有内容,直到读到空白行,然后停止忽略。

// Untested code
std::string s;
// Ignore first block
while(std::getline(std::cin, s) && !s.empty()) {
  /* nothing */
  ;
}
// Don't ignore the second block
while(std::getline(std::cin, s)) {
  std::cout << "You typed: " << s << "n";
}

您可以创建一个过滤流缓冲区,该缓冲区在行进入时读取行,但在看到两个换行符之前阻止转发字符。然后它可以假装这就是预期的一切,直到有东西重置它。代码看起来像这样:

class blockbuf: public std::streambuf {
public:
    blockbuf(std::streambuf* sbuf): sbuf_(sbuf), blocked_(false) {}
    int underflow() {
        std::istream in(this->blocked_? 0: this->sbuf);
        for (std::string line; std::getline(in, line) && !line.empty(); ) {
             this->buffer_ += line + "n";
        }
        if (this->in_) {
            this->buffer_ += "n";
        }
        this->setg(this->buffer_.c_str(), this->buffer_.c_str(),
                   this->buffer_.c_str() + this->buffer_.size());
        this->blocked_ = true;
        return this->gptr() == this->egptr()
             ? traits_type::eof()
             : traits_type::to_int_type(*this->gptr());
    }
    void unblock() { this->blocked_ = false; }
private:
    std::streambuf* sbuf_;
    bool            blocked_;
    std::string     buffer_;
};

您可以使用类似这样的流缓冲区(如果您想通过std::cin使用它,您可以使用std::cin.rdbuf()来代替std::cin的流缓冲):

blockbuf b(std::cin.rdbuf());
std::istream in(&b);
for (std::string block; std::getline(in, block, 0); b.unblock(), in.clear()) {
     processAllLinesUpToEmptyLine(block);
}

显然,如何玩这个游戏有很多变化。。。