Я нашел ответ на этот вопрос для сценариев Python, Java, Linux, но не для C ++:
Я хотел бы записать все выходные данные моей программы на C ++ как в терминал, так и в выходной файл. Используя что-то вроде этого:
int main ()
{
freopen ("myfile.txt","w",stdout);
cout<< "Let's try this";
fclose (stdout);
return 0;
}
выводит его только в выходной файл с именем «myfile.txt» и запрещает его отображение на терминале. Как я могу сделать вывод на оба одновременно? Я использую Visual Studio 2010 Express (если это будет иметь значение).
Заранее спасибо!
Возможное решение: использовать статический поток, похожий на cout-объект, для записи как в cout, так и в файл.
Грубый пример:
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;
}
Вам, вероятно, придется явно обрабатывать потоковые манипуляторы.
Не существует встроенного способа сделать это за один шаг. Вы должны записать данные в файл, а затем вывести данные на экран в два этапа.
Вы можете написать функцию, которая принимает данные и имя файла и делает это для вас, чтобы сэкономить ваше время, какая-то функция регистрации.
У меня есть способ сделать это, и он основан на модели подписчика.
В этой модели вся ваша регистрация ведется «менеджером», а затем у вас есть «подписчики», которые решают, что делать с сообщениями. Сообщения имеют темы (для меня это номер), и регистраторы подписываются на одну или несколько тем.
Для вашей цели вы создаете 2 подписчика, один для вывода в файл, а другой для вывода на консоль.
В логике вашего кода вы просто выводите сообщение, и на этом уровне не нужно знать, что будет с ним делать. В моей модели вы можете сначала проверить, есть ли «слушатели», так как это считается дешевле, чем создание и вывод сообщений, которые в конечном итоге окажутся только в / dev / null (хорошо, вы понимаете, что я имею в виду).
Один из способов сделать это — написать небольшую оболочку, например:
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;
}
Наличие класса вместо функции заставляет вас использовать идиому RAII (https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization)
Чтобы использовать это:
DoubleOutput mystream("myfile");
mystream << "Hello World";