【问题标题】:Getting last char sent to std::cout将最后一个字符发送到 std::cout
【发布时间】:2012-08-17 03:16:11
【问题描述】:

我需要在 main() 执行结束时检查发送到标准输出的最后一个字符(通过std::cout)是否为'\n'(或特定于平台的行尾)。如何对此进行测试?可以安全地假设没有使用 C 风格的 io(如 printf)。

程序是 C++ 的 REPL。它评估 C++ 表达式(或语句)并在标准输出上打印结果。希望输出总是以单个换行符终止。

【问题讨论】:

  • 为什么?你想做什么?
  • 通常最好问问题而不是步骤,但 std::cin.get() 应该可以工作。
  • “最后”是指“最终”还是“最近”?
  • @Lol4t0: 而cos 是“C 输出流”!
  • 糟糕,我误解了意图。在那种情况下,也许只是将标准输出重定向到一个字符串流并在那里操作缓冲区?

标签: c++ iostream cout


【解决方案1】:

@Kevin 给出的答案与此类似。但是我相信它更适合您的需求。而不是使用一些你的流来代替 cout - 你可以用你自己的替换 std::cout 中的 streambuf:

int main() {
   std::streambuf* cbuf = std::cout.rdbuf(); // back up cout's streambuf
   std::cout.flush();
   keep_last_char_outbuf keep_last_buf(cbuf);
   std::cout.rdbuf(&keep_last_buf);          // assign your streambuf to cout

   std::cout << "ala ma kota\n";

   char last_char = keep_last_buf.get_last_char();
   if (last_char == '\r' || last_char == '\n')
      std::cout << "\nLast char was newline: " << int(last_char) << "\n";
   else
      std::cout << "\nLast char: '" << last_char << "'\n";

   std::cout << "ala ma kota";
   last_char = keep_last_buf.get_last_char();
   if (last_char == '\r' || last_char == '\n')
      std::cout << "\nLast char was newline: " << int(last_char) << "\n";
   else
      std::cout << "\nLast char: '" << last_char << "'\n";

   std::cout.rdbuf(cbuf); // restore cout's original streambuf
}

预期输出:

ala ma kota

Last char was newline: 10
ala ma kota
Last char: 'a'

写这样class keep_last_char_outbuf的任务不是很容易,寻找装饰器模式和streambuf接口。

如果你没有时间玩这个 - 看看我的建议ideone link

class keep_last_char_outbuf : public std::streambuf {
public:
    keep_last_char_outbuf(std::streambuf* buf) : buf(buf), last_char(traits_type::eof()) {
        // no buffering, overflow on every char
        setp(0, 0);
    }
    char get_last_char() const { return last_char; }

    virtual int_type overflow(int_type c) {
        buf->sputc(c);
        last_char = c;
        return c;
    }
private:
    std::streambuf* buf;
    char last_char;
};

【讨论】:

  • 这正是我所需要的!谢谢你。这将被纳入volnitsky.com/project/scc 项目
  • @Leonid - 很高兴知道这一点。请记住两件事,我的解决方案不关心:1)多线程 2)在设置keep_last_char_outbuf 后通过cout.rdbuf()-&gt;pubsetbuf(...) 设置外部缓冲区。
【解决方案2】:

除了打印到cout,您还可以定义自己的类流对象,该对象接受标准的ostream 运算符/函数,但在将操作传递给真正的@ 时跟踪最近打印的字符987654323@.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多