2012-04-16 2 views
1

Это вопрос n00b, но Я пишу инструмент на основе nix и хотел бы иметь флаги verbosity, основанные на количестве переданных vvv. Я бы начал печатать отладочные/информационные инструкции в моя программа.Добавление многословия в программу

Мой вопрос: как я могу использовать opargs для этого, так как optargs может анализировать только один символ за раз.

Также предположим, что я знаю, что я на уровне 3-го уровня, все мои заявления на печать должны быть в состоянии if? Или есть умный способ обойти это, используя предварительный процессор?

Также, если кто-то может указать мне на какой-то код онлайн, который делает это, это было бы потрясающе.

Благодаря

Я полагаю, что это, подумал я пост здесь, если кто-то приходит через это в будущем:

В основном для всех моих различных заявлений многословия я определил специальную печать с помощью препроцессора, как :

#define dprintf \ 
    if (verbosity == 1) printf 

Затем я помещаю инструкции в случае необходимости в код, например

dprintf ("Verbosity is at level 1."); 

My Opt atgs выглядит примерно так

case 'v': 
    verbosity++; 
break; 
+0

Вы пытались использовать свой синтаксический анализ с помощью строки «-vvv»?Как правило, это обрабатывается как «-v -v -v», если есть такая возможность. В противном случае вы всегда можете определить три флага: «-v», «-vv» и «-vvv» и установить уровень отладки с помощью этих. В любом случае, это что-то вроде небольшого трюка. Но вы делаете это только один раз. – HonkyTonk

+0

, можно ли использовать препроцессор для определения специального оператора «print» и использовать его для распечатки подробных параметров? – Falcata

+0

Почему бы не просто '-v1',' -v2', '-v3' и т. Д.? –

ответ

1

Как насчет Conditional compilation?

Вы также можете упростить, установив число для подробного уровня вместо того, чтобы передавать это число v's.

#if VERBOSE_LEVEL == 3 
    print("A verbose message"); 
#endif 
+0

Я думаю, что он означает, что уровень детализации продиктован флагами командной строки, что сделает его временем выполнения, а не компилирует время. – Matt

3

Уровень детализации неизвестен во время компиляции, поэтому вам нужно иметь готовый код для обработки любого уровня, который пользователь выбирает.

Простой и понятный способ сделать это - отделить ваши функции ведения журнала в непрозрачном блоке компиляции со статической переменной, отслеживающей уровень детализации. Затем вы инициализируете это чем-то вроде «set_logging_level (level)» и записываете свои функции ведения журнала, защищенные этой статической переменной. Затем вы открываете только функции инициализации и ведения журнала и используете их в своих кодах.

static level = 0; 
void set_logging_level(int l) { level = l; } 

void log_info(char* msg) { 
    // Will always print 
} 

void log_debug(char *msg) { 
    if(level > 0) 
    // Write to stdout or stderr, whichever fits 
} 

void log_details(char *msg) { 
    if(level > 1) 
    // As above 
} 

void log_insanity(char *msg) { 
    if(level > 2) 
    // As above 
} 

Редактировать: Saner условия для регистрации. Особенно, если вы хотите инклюзивного протоколирование, когда уровень детальности идет вверх ...

+0

Я бы сделал это, кроме использования вариационных функций и 'vprintf'. Или, если по какой-то причине у вас нет 'vprintf', вам все равно придется использовать макрос. [Хороший пример - лучший результат Google для vprintf] (http://www.cplusplus.com/reference/clibrary/cstdio/vprintf/). –

0

Я не слишком уверен, если это то, что вы в виду, но это, как я реализовал ее в другом проекте:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

#define TRUE 1 
#define FALSE 0 

int usage(char *name, int quit); 

int main (int argc, char **argv) { 
    int c; 
    static int vlevel = 0; 

    while ((c = getopt(argc, argv, ":abc:d:hv012")) != -1) { 
     int this_option_optind = optind ? optind : 1; 
     switch (c) { 

      case 'v': 
       vlevel++; 
       printf ("verbosity level is %d\n", vlevel); 
       break; 

      case ':':  /* Option without required operand */ 
       fprintf(stderr, "option -%c requires an operand\n", optopt); 
       break; 

      case 'h': 
      case '?': 
       usage(argv[0], TRUE); 
       break; 

      default: 
       printf ("?? getopt returned character code 0%o ??\n", c); 
     } 
    } 

    if (optind < argc) { 
     printf ("non-option ARGV-elements:\n"); 
     while (optind < argc) 
      printf ("\t%s\n", argv[optind++]); 
    } 

    exit (0); 
} 

int usage(char *progname, int quit) 
{ 
    printf ("Usage:\n\t%s [-vh]\n", progname); 
    if (quit) exit(1); 
    return 0; 
} 

Это даст вам что-то вроде следующего:

[email protected]:~$ ./testverbose -h 
Usage: 
    ./testverbose [-vh] 
[email protected]:~$ ./testverbose -vvvv 
verbosity level is 1 
verbosity level is 2 
verbosity level is 3 
verbosity level is 4 
[email protected]:~$ 

оттуда вы должны быть в состоянии использовать переменную vlevel [в основной()] для печати правильного сообщения в течение соответствующего уровня детальности.