2016-05-10 28 views
6

Bitte helfen Sie mir, dieses Problem zu lösen. Dies ist ein Beispielcode, um Zeilennummer, Dateiname und Var-Argumente in C zu erhalten. Als ich das versuchte, habe ich einige Fehler bekommen. Ich bin mir sicher, dass es viele Möglichkeiten gibt, dies zu tun. Aber ich muss vorhandenen Code verwenden, um einige Funktionalität zu erreichen. Jede Hilfe oder Vorschläge wären sehr willkommen.Makro innerhalb von Makro in C

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

#define MY_MACRO1(fmt, args...)    \ 
{            \ 
    char buf_d[1024];      \ 
    MY_MACRO2(__FILE__, __LINE__,call_func(buf_d,sizeof(buf_d),fmt,##args)); \ 
} 

#define MY_MACRO2(__FILE__, __LINE__,fmt, ...) printf("%s : %d -> %s : \n",__FILE__, __LINE__, __VA_ARGS__); 

char * call_func(char *buf_t, size_t size, const char *fmt, ...) 
{ 
    va_list ap; 
    va_start(ap,fmt); 
    vsnprintf(buf_t, size, fmt, ap); 
    va_end(ap); 
    return buf_t; 
} 


int main() 
{ 
    printf("\n Now I am printintg macro....\n"); 
    MY_MACRO1("Macro is working fine..\n"); 
    return 0; 
} 

Ausgang:

Bitte Makroerweiterung finden. Das letzte Argument im Makro (func return value) fehlt.

char buf_d[1024]; 
printf("%s : %d -> %s : \n","file.c",35,);; 

Fehler:

file.c:35:83: error: expected expression 
{ char buf_d[1024]; printf("%s : %d -> %s : \n","file.c", 35,);; }; 
                  ^

1 Fehler erzeugt.

+3

Elefant: Warum ein Makro verwenden? – user4581301

+3

Warum Dual-Tag dieses C und C++, wenn es nicht ist? Sie verwenden eine nicht standardmäßige Compiler-Erweiterung eines Compilers, den Sie in der Frage nicht angegeben haben. Muss es gültig werden? Muss es gültiges C++ werden? Muss es für Ihren speziellen Compiler akzeptabel sein? Alle drei würden dir unterschiedliche Antworten geben. Und warum in aller Welt beschließen, "__FILE__" und "__LINE__" als Makroparameter neu zu definieren ?! – hvd

+0

IIRC 'fmt, args ...' später gefolgt von einem ', ## args' ist eine nicht-portable Erweiterung. Sie können '...' anstelle von 'fmt, args ...' und '__VA_ARGS__' anstelle von' fmt, ## args' verwenden – technosaurus

Antwort

1

Wenn Sie , ... verwenden, bedeutet das, dass Sie ein Argument liefern müssen, was nicht Ihr Fall ist. Sie können nur Ihr Makro ändern, indem Sie die Liste der Argumente benennen und den Präprozessor bei Bedarf dem Komma entziehen:

#define MY_MACRO1(fmt, args...)    \ 
{            \ 
    char buf_d[1024];      \ 
    MY_MACRO2(__FILE__, __LINE__,call_func(buf_d,sizeof(buf_d),fmt,##args)); \ 
} 

#define MY_MACRO2(F,L,fmt,args...) printf("%s : %d -> %s : \n",F, L, fmt, ##args) 
+0

test_macro.c: 30: 2: Warnung: mehr '%' Konvertierungen als Daten Argumente [-W Format] Ich denke, du bist richtig Jean.Aber wenn ich versuchte, bekam ich folgende Warnung .. Es wird etwas Müll anstelle der gewünschten Zeichenfolge gedruckt ..test_macro.c: 20: 69: Hinweis: von Makro 'DEBUG_APMD_V2' erweitert #define DEBUG_APMD_V2 (Datei, Zeile, FMT, args .. .) printf ("% s:% d ->% s: \ n", Datei, Zeile, ## args); ~^ 1 Warnung generiert. – Rock26

+0

Ihr Beispiel geändert, wie ich vorgeschlagen, funktioniert für mich, kann Ihre tatsächliche Situation ein bisschen anders sein? –

+2

Beachten Sie, dass die Notation ohne das Komma vor den Auslassungspunkten eine GCC-Erweiterung (und wahrscheinlich Clang-für-Kompatibilität-mit-GCC) ist. –

2

Was für ein Durcheinander! Lassen Sie uns die Dinge reinigen:

Der Code:

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


#define DEBUG_MSG(_msg, ...) do {print_debug_msg(__FILE__, __LINE__, __FUNCTION__, _msg, ## __VA_ARGS__); }while(0) 


void print_debug_msg(const char * module, int line, const char * func, const char * fmt, ...) 
{ 
    va_list va; 
    char buf[ 1024 ] = {0}; 

    va_start(va, fmt); 
    vsnprintf(buf, sizeof(buf), fmt, va); 
    va_end(va); 

    printf("%s:%d - %s() - %s\n", module, line, func, buf); 
} 


int myfunc(const char * msg) 
{ 
    DEBUG_MSG("Message: %s", msg); 

    return 0; 
} 


int main(int argc, char * argv[]) 
{ 
    DEBUG_MSG("The quick brown fox jumps over the lazy dog."); 

    DEBUG_MSG("Pack my box with five dozen liquor jugs."); 

    myfunc("How vexingly quick daft zebras jump"); 

    myfunc("The five boxing wizards jump quickly."); 

    return 0; 
} 

/* eof */ 

compilieren:

$ gcc -Wall macro.c -o macro 

Testing:

$ ./macro 
macro.c:32 - main() - The quick brown fox jumps over the lazy dog. 
macro.c:34 - main() - Pack my box with five dozen liquor jugs. 
macro.c:24 - myfunc() - Message: How vexingly quick daft zebras jump 
macro.c:24 - myfunc() - Message: The five boxing wizards jump quickly. 

Referenzen:

1) Recommended C Style and Coding Standards (Macros)

2) GCC Manual - Standard Predefined Macros

Hoffe es hilft!