C ++如何同时提示和编写

时间:2019-11-15 17:12:50

标签: c++ cout

阅读以下内容:C++ Writing to file and Console Output at the same time with simple code之后,我试图编写一个函数来处理for循环中的内容。但是我不知道如何将这样的一段代码:setw(3) << right << get<0>(*it_party) << setw(9) << ""完全作为参数传递给函数,以便cout和file都可以使用它。

The helper function I am trying to write:
void print(std::ostream &os1, std::ostream &os2, const [I don't know what to put in here])
{
    os1 << the argument; // cout
    os2 << the argument; // file
}

ofstream file;
file.open("test.txt");

for (auto it_party = parties_.begin(); it_party != parties_.end(); ++it_party) {
    cout << setw(3) << right << get<0>(*it_party) << setw(9) << "";
    file << setw(3) << right << get<0>(*it_party) << setw(9) << "";
    cout << setw(7) << left << get<1>(*it_party) << setw(1) << "";
    file << setw(7) << left << get<1>(*it_party) << setw(1) << "";
    ...
    ...
  }

3 个答案:

答案 0 :(得分:3)

如果您希望像这样将输出串在一起,您可能会发现使用某种“ tee”类更容易:

class Tee {
private:
    std::ostream &os1, &os2;
public:
    Tee(std::ostream &os1, std::ostream &os2) : os1(os1), os2(os2) { }

    template <typename T>
    Tee& operator<<(const T &thing) {
        os1 << thing;
        os2 << thing;
        return *this;
    }
};

这将采用模板参数,因此无论您传递的是right还是setw(3),它都不在乎。您可以像这样使用它:

Tee t(std::cout, std::cout);
t << setw(10) << "right" << " Thing" << setw(9);

答案 1 :(得分:0)

您可以使用std::stringstream轻松地做到这一点。我不知道get<>()是什么,但这是一个基本示例:

#include <string>  
#include <iostream> 
#include <sstream>   
#include <fstream>

void fn(std::string output) {

    std::ofstream file("file.txt");

    std::cout << output;
    file << output;

}

int main() {

    std::stringstream buffer;
    buffer << "some random text" << std::endl;

    fn(buffer.str());

    return 0;
}

答案 2 :(得分:0)

不幸的是,您不能将所有这些东西仅作为一个参数传递。但是有一些高级技术可以为您提供帮助,例如variadic templates和C ++ 17 fold expressions

可变参数模板是一项功能,例如,它使您可以在编译时传递未知量的不同类型的参数。您可以在标准库(例如std::tuple)中看到此类示例。

折叠表达式是与前一个表达式结合使用的又一个功能。它允许您编写非常简单的可变参数模板代码:

template<typename ...Args>
void printer(const Args &... args) {
    (std::cout << ... << args) << '\n';
}

在这里,我们看到了一个函数,该函数将一些参数const &带入某些参数(我们不知道它们的数量或不同的类型),但是我们有一个很漂亮的东西,例如args,一个参数包,代表我们的论点,而Args作为其类型“打包”在一起;

您可以使用它来将任意参数传递给流:

template<typename ...Args>
void printer(const Args &... args) {
    (std::cout << ... << args);
    (file << ... << args);
}

此解决方案还有一些其他需要改进的地方,例如perfect forwarding,但这些还有待进一步研究。