声明另一个类似于cout的对象输出流

时间:2014-03-01 17:29:38

标签: c++ cout

我只是好奇是否有可能以某种方式声明类似于cout的东西,但是要定义它的功能。例如:

SetCursorPosition(output_handle, some_COORD);
cout_coord << "Hi\nthere!";

生成输出

 .
               Hi
               there!

4 个答案:

答案 0 :(得分:0)

好的cout不是一个函数,它实际上是一个std :: ostream。您可以创建自己的写入stdout的ostream。

答案 1 :(得分:0)

您可以使用运算符重载使<<基本上做任何事情(只是谷歌“c ++运算符重载”,你会发现大量的信息),但在你的问题中这样的事情通常被认为是滥用运营商超载。重载运算符旨在使代码更易于阅读。在C ++中,每个人都知道<<表示“输出内容”,就像+=表示“以数学方式添加内容”而=表示“分配内容”。

当我在某段代码中看到<<时,我当然不会将其读作“设置光标位置然后打印文本”。你可以像这样实现它,但这是糟糕的编程风格,类似于错误的普通函数。

答案 2 :(得分:0)

实现此逻辑的方法是创建一个自定义流缓冲区,该缓冲区在其overflow()方法中的适当位置写入,然后使用此流缓冲区创建合适的std::ostream。这是一个粗略的草图,看起来如何:

class posbuf: public std::streambuf {
    int d_row;     // current row
    int d_column;  // column where to start output
    void move() { /* use curses, VT100 codes, whatever to move the cursor */ }
    int overflow(int c) {
        if (c == traits_type::eof()) { return traits_type::not_eof(c); }
        if (c == '\n') { ++this->d_row; this->move(); return '\n'; }
        return std::cout << traits_type::to_char_type(c)? c: traits_type::eof();
    }
    int sync() {
        return std::cout.flush()? 0: -1;
    }
public:
    posbuf(int row, int column): d_row(row), d_column(column) { this->move(); }
};
struct oposstream: private virtual posbuf, public std::ostream {
    oposstream(int row, int column): posbuf(row,c column), std::ostream(this) {}
};

int main() {
    oposstream out(4, 10);
    out << "hello\nworld";
}

除了几个可能的拼写错误以及有关如何实际移动光标的详细信息之外,上面的代码实际上应该可以工作并创建一个std::ostream,可以在std::ostream&所需的任何地方传递。任何使用某些模板重载输出操作符的尝试都不会起作用。

答案 3 :(得分:0)

感谢Christian Hackl和其他用户删除了他们的答案,我做了一项研究,找到了我想要的答案。

如果有人仍然好奇我在问题中的例子变成了:

std::ostream& operator<<(std::ostream& left, const char * right)
{
    string sRight = right;
    CONSOLE_SCREEN_BUFFER_INFO con;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &con);
    COORD xy;
    xy.X = con.dwCursorPosition.X;
    xy.Y = con.dwCursorPosition.Y;
    for (int i = 0; i < sRight.length(); i++)
    {
        if (sRight[i] == '\n')
        {
            xy.Y++;
            SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), xy);                
            continue;
        }
        cout << sRight[i];
    }
    return left;
}

然后你就是:

SetConsoleCursorPosition(output_handle, some_COORD);
cout_coord << "Hi\nthere!";

“嗨”和“那里!”对于some_COORD给出的每个x都是一个在另一个之下!