Выборочное подавление вывода на терминал C ++. - PullRequest
1 голос
/ 21 сентября 2011

У меня есть куча .cpp файлов, которые вместе обрабатывают одинаковые файлы данных, но разных размеров.Для больших файлов данных я хочу провести некоторые временные исследования функций внутри файлов .cpp.

Я хотел бы подавить вывод результатов для этих больших наборов данных и печатать только результаты синхронизации.Для небольших наборов данных я хотел бы распечатать на экране, чтобы проверить правильность алгоритма / кода.

Вместо того, чтобы многократно комментировать / раскомментировать соответствующие операторы cout и перекомпилировать, я хотел бы использовать аргументы командной строки (или некоторые другие методы) для выборочного подавления вывода.

Есть предложения?Наивный, который я могу придумать, это использовать argc и argv, но я не уверен, являются ли они глобальными переменными, которые могут использоваться функциями в разных файлах.

Ответы [ 4 ]

4 голосов
/ 21 сентября 2011

Ваша интуиция верна - используйте значения argc и argv, переданные в вашу функцию main, но они не являются глобальными переменными.Вам нужно как-то сделать свою информацию глобальной: я бы рекомендовал один раз проанализировать аргументы и сохранить набор глобальных флагов, которые можно легко запросить.

Например:

// In a common header file that gets included in each source file
extern bool g_bFlag1;
extern bool g_bFlag2;
...

// In your main source file
bool g_bFlag1 = false;
bool g_bFlag2 = false;
...
int main(int argc, char **argv)
{
    // Parse command line and store results in global flags
    for (int i = 1; i < argc; i++)
    {
        if (strcmp(argv[i], "--flag1") == 0)
            g_bFlag1 = true;
        else if (strcmp(argv[i], "--flag2") == 0)
            g_bFlag2 = true;
        else
            ;  // etc.
    }
}

// In any other source file:
if (g_bFlag1)
{
    // do stuff if and only if g_bFlag1 is set
}

ТогдаВы можете передать --flag1 в командной строке.Для более сложного разбора аргументов я бы предложил использовать такую ​​библиотеку, как GNU getopt .

4 голосов
/ 21 сентября 2011

Конечно argv и argc являются , а не глобальными переменными, поскольку они являются явно локальными переменными области действия main():

int main(int argc, char * argv[]) { /* ... */ }

Для удобной обработки опций, вы можете посмотреть на getopt.h.


Один из способов подавления вывода - использовать grep или перенаправление файлов на оболочке (time ./prog > /dev/null),но это по-прежнему стоит затрат на фактические функции вывода.

Я предлагаю две возможные идеи:

  1. Окружите свои критические функции вызовами clock() и выполните измерениеи сообщать о себе.

  2. Разрешить пользователю передавать параметр многословия (либо во время выполнения с параметром командной строки, либо во время компиляции с #define) и печатать только в зависимости отуровень детализации.

Для идеи (1) я использую следующие макросы:

#define CLOCK_TICK(acc, ctr)  ctr = std::clock()
#define CLOCK_TOCK(acc, ctr)  acc += (std::clock() - ctr)
#define CLOCK_RESET(acc) acc = 0
#define CLOCK_REPORT(acc) 1000. * double(acc) / double(CLOCKS_PER_SEC)

Для идеи (2) я бы сделал что-то вроде этого:

#ifndef VERBOSE
#  define VERBOSE 0
#endif

#if VERBOSE > 0
// print level 1
#if VERBOSE > 1
// print level 2
#endif
#endif

Затем вы можете скомпилировать с -DVERBOSE=3 и т. Д., Чтобы включить ведение журнала на определенном уровне.

Если это слишком вручную, вам следует изучить подходящую структуру ведения журнала для вашего приложения.

2 голосов
/ 21 сентября 2011

По умолчанию все, что вам нужно для вывода, это stdout (как cout) и stderr (как cerr).

Таким образом, некоторые опции:

  • записывают время в stderr вместо stdout и направляют их в разные места командной строки
  • открыть файл журнала дляваши данные синхронизации и запишите в этот
  • тег каждой строки вашего вывода чем-то вроде «[хронометраж]», затем используйте grep в командной строке, чтобы показать только те выходные строки, которые вы хотите видеть.
0 голосов
/ 21 сентября 2011

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

/*inside file_name.cpp*/

//uncomment next line to activate debug print on this file
//#define FILE_NAME_DEBUG  
#ifdef FILE_NAME_DEBUG
cout << "activate debug print\n";
#endif

Этот подход может выборочно подавить оператор печати, но требует перекомпиляции модуля каждый раз.

...