Как перегрузить printf или cout - PullRequest
5 голосов
/ 04 мая 2011

Я использую операторы cout в своей программе для целей отладки.Я хотел бы сделать функцию, которая работает как она, или работает как printf, но чувствительна к глобальной переменной.Если эта глобальная переменная имеет значение true, она будет выведена на экран.Если оно ложно, то ничего не печатается.Уже есть такая функция?Если нет, то как это сделать?

Ответы [ 3 ]

5 голосов
/ 04 мая 2011

Примерно так:

int myPrintf(const char* format, ...) 
{
  if (globalCheck == 0)
    return 0
  va_list vl;
  va_start(vl, format);
  auto ret = vprintf(format, vl);
  va_end(vl);
  return ret;
}

va_start и va_end принимают аргументы в ... и инкапсулируют их в va_list. с этим va_list вы можете затем vprintf, который является вариантом printf, предназначенным именно для этой потребности.

Примечание: обычно использование глобальных переменных - это плохая практика. Лучше всего сделать это в таком классе -

class ConditionalPrinter {
public:
  ConditionalPrinter() : m_enable(true) {}
  void setOut(bool enable) { m_enable = enable; }
  int myPrintf(const char* format, ...);
private:
  bool m_enable;
}

и затем проверить m_enable вместо глобальной переменной. Использование этого выглядит следующим образом:

ConditionalPrinter p;
p.myPrintf("hello %d", 1);   // printed
p.setOut(false);
p.myPrintf("hello2 %d", 1);  // not printed

....

3 голосов
/ 04 мая 2011

Не пиши это сам. Делать это правильно намного сложнее, чем вы думаете. Еще сложнее, когда вам нужны потоки и эффективность. Используйте одну из существующих библиотек журналов, например:

  • glog: http://code.google.com/p/google-glog/ (я предпочитаю это - он легкий и делает то, что должен)
  • Log4cpp http://log4cpp.sourceforge.net/ (мощный и конфигурируемый, совместимый с популярным журналом Java)
  • ... добавить свой любимый в эту вики
2 голосов
/ 04 мая 2011

Как кто-то еще сказал, есть несколько хороших каркасов регистрации.Однако, если вы хотите сделать свой собственный бросок, первое, что нужно отметить, это то, что cout - это не функция, а поток.Функция operator<<.Что вы можете сделать, это примерно так:

/* trace.h */
extern ostream debug;

void trace_init();
void trace_done();

/* trace.cpp */
#include "trace.h"
ostream debug(cout.rdbuf());
static ofstream null;

void trace_init()
{
    null.open("/dev/null");
    if(output_is_disabled) {  // put whatever your condition is here
        debug.rdbuf(null.rdbuf());
    }
}

void trace_done()
{
    null.close();
}

Возможно, вам придется немного подстроиться, если вы на платформе без /dev/null.Это позволяет вам писать

debug << "here's some output << endl;

, и если у вас включен вывод, он будет записывать в cout.Если нет, он напишет в /dev/null, где вы ничего не увидите.

В этом отношении вы можете просто установить rdbuf в cout где-нибудь, где вы не увидите этот вывод, но я бы обнаружил, чтобыть действительно плохой идеей.Создание новых потоков дает вам гораздо больше гибкости в управлении выходными данными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...