2016-03-18 10 views
0

Ich bin ein ausführlicher Modus implementieren. Hier ist, was ich versuche zu tun: Definieren Sie eine globale Variable VERBOSE (in verbose.h) in einer Weise, dass Dateien, die ausführliche Angaben benötigen, nur diese Datei enthalten müssen. Zum Beispiel:Ausführlich in C implementieren

verbose.h:

void setVerbose(int test); 

verbose.c:

#include "verbose.h" 

// define VERBOSE if called 
void setVerbose(int test) { 
    if (test) { 
     #ifndef VERBOSE 
     #define VERBOSE 
     #endif 
    } 
} 

point.h:

typedef struct Point Point; 
struct Point { 
    int x, y; 
}; 

void printPoint(Point *point); 

point.c:

#include "point.h" 
#include "verbose.h" 

void printPoint(Point *point) { 
    #ifdef VERBOSE 
     printf("My abscissa is %d\n", point->x); 
     printf("My ordinate is %d\n", point->y); 
    #endif 

    printf("[x,y] = [%d, %d]\n", point->x, point->y); 
} 

Und die Haupt:

main.c:

wollte sind
$ gcc -o test main.c point.c verbose.c 

Die Ausgänge:

$ ./test 
    [x,y] = [5, 7] 

$ ./test -v 
    My abscissa is 5 
    My ordinate is 7 
    [x,y] = [5, 7] 

Problem ist, es

#include "verbose.h" 
#include "point.h" 

int main(int argc, char *argv[]) { 
    if (argc >= 2 && !strcmp(argv[1], "-v")) 
     setVerbose(1); 

    Point *p = init_point(5,7); 
    printPoint(p); 

    return 0; 
} 

Die ausführbare Datei mit produziert wurde scheint, dass VERBOSE nicht in Punkt.c beim Aufrufen von printPoint() definiert ist.

+2

Bitte wieder lesen das Konzept eines Pre-Prozessor . –

+4

'# define' ist eine ** Präprozessor ** Direktive. Ein #define in eine if-Anweisung einzufügen, ist sinnlos. Dieses '# define' wird übersetzt, bevor das Programm kompiliert wird. –

+0

Die anderen haben das Problem erwähnt, daher schlage ich Ihnen vor, eine ** Protokollierungsklasse ** anstelle Ihrer derzeitigen Vorgehensweise zu verwenden. Es ist viel flexibler. Zum Beispiel schrieb ich vor einiger Zeit eine für Arduino https://abrushforeachkeyboard.wordpress.com/2014/06/17/arduino-adding-a-logger-class-with-ac-style-print-of-messages/ –

Antwort

0

Präprozessorbefehle werden zur Kompilierzeit festgelegt, nicht zur Laufzeit, daher funktioniert Ihr System nicht. Was ich stattdessen empfehlen würde, ist eine globale bool Verbose und Bereitstellung einer Funktion zum Drucken (oder nicht).

verbose.h

#include <stdbool.h> 

int verbose(const char * restrict, ...); 
void setVerbose(bool); 

verbose.c

#include "verbose.h" 
#include <stdbool.h> 
#include <stdarg.h> 
#include <stdio.h> 

bool Verbose = false; 

void setVerbose(bool setting) { 
    Verbose = setting; 
} 

int verbose(const char * restrict format, ...) { 
    if(!Verbose) 
     return 0; 

    va_list args; 
    va_start(args, format); 
    int ret = vprintf(format, args); 
    va_end(args); 

    return ret; 
} 

main.c

#include "verbose.h" 
#include <stdbool.h> 

int main() { 
    verbose("Verbose is off\n"); 

    setVerbose(true); 

    verbose("Verbose is on\n"); 

    int foo = 42; 

    verbose("Number: %d\n", foo); 

    return 0; 
} 
+1

* Präprozessor Befehle werden zur Kompilierzeit entschieden * - Das ist nicht korrekt, der Preprozessor setzt vor dem Compiler ein –

+0

@EdHeal Sie sind technisch korrekt! ... und es ändert sich nicht die Antwort ein Bit. Das Wichtige ist, dass es nicht zur Laufzeit passiert. Ich kann 't herausfinden, wie Pre-Prozessor vs Kompilieren vs Laufzeit zu erklären, ohne die Antwort unnötig kompliziert, vielleicht können Sie in Ihrer eigenen Antwort oder eine Bearbeitung? – Schwern

+1

Ich werde darüber nachdenken, dies für das Poster zu erklären –