C/C++连续两次输入 Enter 后或在 2 个换行符后如何从 stdin 读取

发布于 2024-12-28 16:36:16 字数 517 浏览 3 评论 0原文

我试图让用户向控制台输入一段文本,只有在连续按两次 Enter 后,或者换句话说,当在已经是空白的行上按 Enter 时,我的程序才会从 stdin 读取该文本块。但是,我想继续从标准输入读取,所以基本上,只有在已经是空行的情况下按下 Enter 时才从标准输入读取。然后冲洗并重新启动。

用户输入示例:

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);

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

I'm trying to have the user input a block of text to the console that my program will read from stdin only after enter has been hit twice in a row or, said in a different way, when enter is hit on an already blank line. But, I want to continue reading from stdin so basically, only read from stdin when enter is hit while on an already blank line. Then flush and restart.

Example of user input:

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

I haven't been able to find an input function capable of specifying this behavior.

Also, I've tried a few methods using single character retrieval functions but I haven't been able to get it work correctly.

Anyone know of a way to do this elegantly?

Answer implemented:

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

Obviously buffer overflow needs to be dealt with before using this. Just an example.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

╰つ倒转 2025-01-04 16:36:16

基本上,您希望忽略序列 \n\n 之前的输入。你可以这样做:

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

Basically, you want to ignore the input until the sequence \n\n. You can do it with:

while (getchar()!='\n' || getchar()!='\n');
//read the input now
风和你 2025-01-04 16:36:16

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

// 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";
}

Ignore everything until you read in a blank line, then stop ignoring.

// 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";
}
爱她像谁 2025-01-04 16:36:16

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

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);
}

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

You can create a filtering stream buffer which reads lines as they come in but blocks forwarding characters until it has seen two newlines. It could then pretend this is all what is to be expected until something resets it. The code would look something like this:

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_;
};

You would use this stream buffer something like this (if you want to use it via std::cin you can use std::cin.rdbuf() to replace std::cin's stream buffer):

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

Obviously, there are many variations on how to play this game...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文