LINUX.ORG.RU

C++ скопировать stdout в ofstream


0

0

На данный момент у меня тупо дублируются куски текста для выведения их на консоль и (аналогичных кусков) в лог. Как можно правильно сделать вывод одного и того же текста (вида "переменная: значение переменной") на stdout и в файл?

anonymous

> На данный момент у меня тупо дублируются куски текста для выведения их на консоль и (аналогичных кусков) в лог. Как можно правильно сделать вывод одного и того же текста (вида "переменная: значение переменной") на stdout и в файл?

Писать и в stdout и в файл, рассматривая их как ostream.

cout << text << endl;

ofstream f("log.txt");

f << text << endl;

f.close();

gaa ★★
()
Ответ на: комментарий от gaa

Именно это я и хочу устранить - повторение "text", потому чо тексты у меня некороткие и каждое исправление приходится делать дважды.

anonymous
()
Ответ на: комментарий от dont

А без библиотек никак? Не хочется из-за такой мелочи библиотеки дергать, кроме того хотелось бы программку распространять потом также среди людей, которые имеют лишь смутные представления о сторонних библиотеках и их установке.

anonymous
()
Ответ на: комментарий от anonymous

Re^2: C++ скопировать stdout в ofstream

> Именно это я и хочу устранить - повторение "text", потому чо тексты у меня некороткие и каждое исправление приходится делать дважды.

Ну создай класс DebugInfoKeeper, у которого в кончтрукторе будут указываться все нужные параметры(переменная, её значение) и определи в нём ostream &operator<<(const ostream &out);

gaa ★★
()
Ответ на: комментарий от anonymous

Решил пока сделать так:
#define TEXT "var1: " << var1 << endl \
<< "var2: " << var2 << endl \
...
<< "Note: blabla" << endl

cout << TEXT;
logfile << TEXT;

Вроде пашет.

anonymous
()

Написать класс-обертку и реализовать шаблонный operator<< ?

anonymous
()

>Как можно правильно сделать вывод одного и того же текста (вида 
>"переменная: значение переменной") на stdout и в файл?

если правильно, то нужно сляпать простенький streambuf что то типа 


#include <streambuf>
#include <ofstream>

using namespace std;

template< typename Elem = char, typename Traits = char_traits<Elem> >
class pipeline_buffer : public std::basic_streambuf<Elem, Traits> {
  typedef std::basic_streambuf<Elem, Traits> super_t; 
  typedef typename super_t::int_type int_type;
	
public:
  pipeline_buffer( ostream& f, ostream& s) 
  : f_(f.rdbuf()), s_(s.rdbuf())
  {
    f.rdbuf(this);
    s.rdbuf(this);
  }
protected:
  /*override*/
  int_type overflow (int_type c) {
     if ( f_->sputc(c)!= Traits::eof() 
          && 
          s_->sputc(c)!= Traits::eof() )
	return Traits::not_eof(c);
     else
	return Traits::eof();		
  }

protected:
  super_t *f_, *s_;
};


int main(void) {
	
  ofstream log("aaa.log");
  pipeline_buffer<> pipe(log, cerr);	

  cerr << "Booooom!!!" << endl;	
  // или 
  // log << "Booooom!!!" << endl;
  // без разницы  
}


лучше конечно использовать специализированную библиотеку для логинга.
всякие там log4cxx(cpp) очень плохи (протечки и прочие бяки) и лучше 
ими не пользоваться, а пользоваться например этим:

http://www.torjo.com/log2/doc/html/index.html

aydef
()
Ответ на: комментарий от aydef

OMFG. Уже интереснее, но когда же нюбу с этим разбираться?..

anonymous
()

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

anonymous
()

Мне только кажется, или и в самом деле с stdio жить проще, чем со stream?

#include <stdio.h>
#include <stdarg.h>

void log(char *format, ...) {
va_list ap;

va_start(ap, format);
vprintf(format, ap);
va_end(ap);

va_start(ap, format);
vprintf(format, ap); // заменить на vfprintf в нужный файл
va_end(ap);
}

int main() {
log("Hello %s! %d+%d = %d!\n", "world", 2, 2, 2+2);
return 0;
}

alexsaa
()
Ответ на: комментарий от aydef

Ну она тоже не идеальна, ее видь в буст не приняли.

dont
()
Ответ на: комментарий от anonymous

>А без библиотек никак? Не хочется из-за такой мелочи библиотеки дергать, кроме того хотелось бы программку распространять потом также среди людей, которые имеют лишь смутные представления о сторонних библиотеках и их установке

Да, в С++ лучше без библитек, действительно.

Absurd ★★★
()
Ответ на: комментарий от aydef

>>Как можно правильно сделать вывод одного и того же текста (вида ?>"переменная: значение переменной") на stdout и в файл?

>если правильно, то нужно сляпать простенький streambuf что то типа

Блин, как же задалбывает каждый раз вычищать это говно и менять на нормальный человеческий stdio.

Absurd ★★★
()
Ответ на: комментарий от Absurd

>Да, в С++ лучше без библитек, действительно.

Если это ирония, то ключевыми словами там были "мелочь" и "сторонняя библиотека"

>человеческий stdio

Это как?

anonymous
()
Ответ на: комментарий от anonymous

>>Да, в С++ лучше без библитек, действительно.

>Если это ирония, то ключевыми словами там были "мелочь" и "сторонняя библиотека"

Это не мелочь. Логирование *важно*.

>>человеческий stdio

>Это как?

Меньше в 5-10 раз чем iostream и быстрее в 2-5 раз. (С) Скот Мейерс, More Effective C++.

От себя еще могу говна подлить, но не сейчас, вечером.

Absurd ★★★
()
Ответ на: комментарий от Absurd

Вы, вероятно, просто никогда не сталкивались с проблемами, которые возникают из-за stdio. Вроде

short k;

printf("%d", k);

gzh
()
Ответ на: комментарий от gzh

>Вы, вероятно, просто никогда не сталкивались с проблемами, которые возникают из-за stdio. Вроде

Этой проблемы не существует. Ты ее выдумал.

Absurd ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.