2014-01-20 4 views
4

я нашел ответ на этот вопрос для Python, Java, сценария Linux, но не C++:Записи как терминал и файл C++

Я хотел бы написать все выходы моих C++ программы, чтобы как терминал и выход файл. Используя что-то вроде этого:

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

выводит его только выходной файл с именем «myfile.txt», и предотвращает его от показывать на терминале. Как я могу сделать вывод одновременно? Я использую visual studio 2010 express (если это будет иметь значение).

Заранее благодарен!

+3

Вы можете использовать другой объект потока, один из которых дублируют вызовы в файл и стандартный вывод – StoryTeller

+0

возможного дубликата [Выборочный C++ класса соиЬ - outpu t для консоли и файла журнала] (http://stackoverflow.com/questions/5942229/custom-c-cout-class-output-to-both-console-and-log-file) – feetwet

ответ

1

Нет встроенного способа сделать это за один шаг. Вы должны записать данные в файл, а затем записать данные на экране в два этапа.

Вы можете написать функцию, которая принимает данные и имя файла, и делает это для вас, чтобы сэкономить ваше время, какая-то функция ведения журнала.

5

Возможное решение: использовать статический поток 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; 
} 

Вам, вероятно, придется явно обрабатывать потоковые манипуляторы, хотя.

Here is my library implementation.

+0

@Aly: если вы удовлетворенный, не возражаете ли вы принять этот ответ, чтобы вопрос мог быть отмечен как «разрешенный»? Благодарю. Кроме того, вы можете опубликовать свой собственный ответ и принять его. –

1

У меня есть метод, чтобы сделать это, и он основан на абонентской модели.

В этой модели все ваши протоколирования передаются менеджеру «регистрации», и у вас есть «подписчики», которые решают, что делать с сообщениями. В сообщениях есть темы (для меня число) и регистраторы подписываются на одну или несколько тем.

Для вашей цели вы создаете 2 подписчика, один из которых выводит файл, а другой - на консоль.

В логике вашего кода вы просто выводите сообщение, и на этом уровне не нужно знать, что с ним делать. В моей модели, хотя вы можете сначала проверить, есть ли какие-либо «слушатели», поскольку это считается более дешевым, чем создание и вывод сообщений, которые будут только в/dev/null (ну, вы знаете, что я имею в виду).

+0

Приобретено, потому что это хороший ответ; однако он может быть слишком тяжелым для того, чего хочет OP. –

0

Один из способов сделать это было бы написать небольшую обертку, чтобы сделать это, например:

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"; 
+0

Я думаю, вам нужно немного расширить ответ. Он не работает в текущей форме. –

 Смежные вопросы

  • Нет связанных вопросов^_^