正在将最后一个字符发送到std::cout

Getting last char sent to std::cout

本文关键字:std cout 最后一个 字符      更新时间:2023-10-16

在main()执行结束时,我需要检查(通过std::cout)发送到stdout的最后一个字符是否是'n'(或特定于平台的行尾)。如何对此进行测试?可以放心地假设没有使用C样式io(如printf)。

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

这与@Kevin给出的答案相似。不过我相信它更适合你的需要。您可以将std::cout中的streambuf替换为自己的:,而不是使用一些流来代替cout

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 kotan";
   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的任务并不容易,请查找decorator模式和streambuf接口。

如果你没有时间玩这个-看看我的建议视频链接

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

您可以定义自己的类似流的对象,而不是打印到cout,该对象接受标准的ostream运算符/函数,但在将操作传递到真正的cout时跟踪最近打印的字符。