使std::cout在同一行中一个接一个地输出多个字符串

Make std::cout output multiple string in the same row one after the other

本文关键字:一个 字符串 输出 std cout 一行      更新时间:2023-10-16

标题一团糟,只看到代码可能会快得多

p1_dado = rand() % 6 + 1;
        switch (p1_dado) {
        case 1:
            cout << ".-----." << endl;
            cout << "|     |" << endl;
            cout << "|  o  |" << endl;
            cout << "|     |" << endl;
            cout << "._____." << endl << endl;
            p1_somma = p1_somma + p1_dado;
            break;
        case 2:
            cout << ".-----." << endl;
            cout << "| o   |" << endl;
            cout << "|     |" << endl;
            cout << "|   o |" << endl;
            cout << "._____." << endl << endl;
            p1_ndadi--;
            break;
        case 3:
            cout << ".-----." << endl;
            cout << "|o    |" << endl;
            cout << "|  o  |" << endl;
            cout << "|    o|" << endl;
            cout << "._____." << endl << endl;
            p1_somma = p1_somma + p1_dado;
            break;
        case 4:
            cout << ".-----." << endl;
            cout << "| o o |" << endl;
            cout << "|     |" << endl;
            cout << "| o o |" << endl;
            cout << "._____." << endl << endl;
            p1_somma = p1_somma + p1_dado;
            break;
        case 5:
            cout << ".-----." << endl;
            cout << "| o o |" << endl;
            cout << "|  o  |" << endl;
            cout << "| o o |" << endl;
            cout << "._____." << endl << endl;
            p1_ndadi--;
            break;
        case 6:
            cout << ".-----." << endl;
            cout << "| o o |" << endl;
            cout << "| o o |" << endl;
            cout << "| o o |" << endl;
            cout << "._____." << endl << endl;
            p1_somma = p1_somma + p1_dado;
            break;
        }

我还应该提到,这段代码位于for循环中,因此switch案例将运行4-5次。这种输出方式是所有的骰子叠在一起,有没有办法在1"行"中显示所有的骰子?类似:

1 2 3 4 5

而不是:

1
2
3
4
5

感谢您的帮助:)

假设您安装了一些拦截和重新排列输出的东西,实际输出基本上可以保持不变。由于我倾向于将编译后的行按键发送到流的flush中,因此唯一真正需要的更改是用'n'来代替对std::endl的过度使用。这是我强烈推荐的东西(有关解释,请查看链接)。

因此,假设定义了一个叫做dicebuf的东西,main()函数可能看起来是这样的(有趣的部分是函数内部的第一个定义):

int main()
{
    dicebuf buf(std::cout);
    for (int i = 0; i != 5; ++i)
    {
        int p1_dado = rand() % 6 + 1;
        switch (p1_dado) {
        case 1:
            std::cout << ".-----." << 'n';
            std::cout << "|     |" << 'n';
            std::cout << "|  o  |" << 'n';
            std::cout << "|     |" << 'n';
            std::cout << "._____." << 'n' << 'n';
            break;
        case 2:
            std::cout << ".-----." << 'n';
            std::cout << "| o   |" << 'n';
            std::cout << "|     |" << 'n';
            std::cout << "|   o |" << 'n';
            std::cout << "._____." << 'n' << 'n';
            break;
        case 3:
            std::cout << ".-----." << 'n';
            std::cout << "|o    |" << 'n';
            std::cout << "|  o  |" << 'n';
            std::cout << "|    o|" << 'n';
            std::cout << "._____." << 'n' << 'n';
            break;
        case 4:
            std::cout << ".-----." << 'n';
            std::cout << "| o o |" << 'n';
            std::cout << "|     |" << 'n';
            std::cout << "| o o |" << 'n';
            std::cout << "._____." << 'n' << 'n';
            break;
        case 5:
            std::cout << ".-----." << 'n';
            std::cout << "| o o |" << 'n';
            std::cout << "|  o  |" << 'n';
            std::cout << "| o o |" << 'n';
            std::cout << "._____." << 'n' << 'n';
            break;
        case 6:
            std::cout << ".-----." << 'n';
            std::cout << "| o o |" << 'n';
            std::cout << "| o o |" << 'n';
            std::cout << "| o o |" << 'n';
            std::cout << "._____." << 'n' << 'n';
            break;
        }
    }
}

这里的想法是dicebuf构造函数注入一个自定义流缓冲区,用于聚合行。它只是不输出内容,只是向当前行添加字符。如果遇到换行符('n'),它将转到下一行。如果在一行中遇到两个换行符,则认为是时候回到顶部并继续添加到当前行了。

创建这样一个拦截输出的实用程序是通过实现一个合适的流缓冲区来完成的,即从std::streambuf派生的类。下面是一个示例实现:

#include <utility>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <string>
#include <vector>
struct dicebuf
    : std::streambuf
{
    std::ostream&                       out;
    std::streambuf*                     sbuf;
    std::vector<std::string>            rows;
    std::vector<std::string>::size_type row;
public:
    dicebuf(std::ostream& out)
        : out(out)
        , sbuf(out.rdbuf())
        , rows(1)
        , row(0) {
        out.rdbuf(this);
    }
    ~dicebuf() {
        this->sync();
        this->out.rdbuf(this->sbuf);
    }
    int overflow(int c) {
        if (c != std::char_traits<char>::eof()) {
            if (c == 'n') {
                if (this->rows[this->row].empty()) {
                    this->row = 0;
                }
                else {
                    ++this->row;
                    if (this->rows.size() == this->row) {
                        this->rows.push_back(std::string());
                    }
                }
            }
            else {
                this->rows[this->row].push_back(c);
            }
        }
        return std::char_traits<char>::not_eof(c);
    }
    int sync() {
        std::ostream out(this->sbuf);
        std::copy(this->rows.begin(), this->rows.end(),
                  std::ostream_iterator<std::string>(out, "n"));
        this->sbuf->pubsync();
        this->row = 0;
        this->rows.resize(0);
        this->rows.push_back(std::string());
        return 0;
    }
};

与上面的main()一起,它应该根据需要产生输出。如果你想要多行结果,你只需要注入一个flush,例如,使用

std::flush;

在战略层面。

代码片段:

char* hline = ".-----.";
char* dice[6][3] = { {"|     |", "|  o  |", "|     |" }, { ... }}; // 3 middle lines for each dice
for (int l=0; l < 5; ++l) {
  for(int i=0; i < 6; ++i) // or any random dice sequence with index = dice value - 1
    cout << (l == 0 || l == 4) ? hline : dice[i][l-1] << " ";
  cout << "n";
}
相关文章: