Writing to both terminal and file c++

妖精的绣舞 提交于 2019-12-23 13:07:20

问题


I found this question answered for Python, Java, Linux script, but not C++:

I'd like to write all outputs of my C++ program to both the terminal and an output file. Using something like this:

int main ()
{
freopen ("myfile.txt","w",stdout);
cout<< "Let's try this"; 
fclose (stdout);
return 0;
}

outputs it to only the output file named "myfile.txt", and prevents it from showing on the terminal. How can I make it output to both simultaneously? I use visual studio 2010 express (if that would make any difference).

Thanks in advance!


回答1:


Possible solution: use a static stream cout-like object to write both to cout and a file.

Rough example:

struct LogStream 
{
    template<typename T> LogStream& operator<<(const T& mValue)
    {
        std::cout << mValue;
        someLogStream << mValue;
    }
};

inline LogStream& lo() { static LogStream l; return l; }

int main()
{
    lo() << "hello!";
    return 0;
}

You will probably need to explicitly handle stream manipulators, though.

Here is my library implementation.




回答2:


There is no built in way to do this in one step. You have to write the data to a file and then write the data out on screen in two steps.

You can write a function that takes in the data and the filename and does this for you, to save you time, some sort of logging function.




回答3:


I have a method to do this, and it is based on a subscriber model.

In this model all your logging goes to a "logging" manager and you then have "subscribers" that decide what to do with the messages. Messages have topics (for me a number) and loggers subscribe to one or more topic.

For your purpose, you create 2 subscribers, one that outputs to the file and one that outputs to the console.

In the logic of your code you simply output the message, and at this level not need to know what is going to be done with it. In my model though you can check first if there are any "listeners" as this is considered cheaper than constructing and outputting messages that will only end up in /dev/null (well you know what I mean).




回答4:


One way to do this would be to write a small wrapper to do this, for example:

class DoubleOutput
{
public:
  // Open the file in the constructor or any other method
  DoubleOutput(const std::string &filename);   
  // ...
  // Write to both the file and the stream here
  template <typename T>
  friend DoubleOutput & operator<<(const T& file);
// ...
private:
  FILE *file;
}

To have a class instead of a function makes you use the RAII idiom (https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization)

To use it:

DoubleOutput mystream("myfile");
mystream << "Hello World";


来源:https://stackoverflow.com/questions/21232517/writing-to-both-terminal-and-file-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!