2008-10-12 15 views
43

उदाहरण के लिए, 'func_name' को दो बार लिखने से कैसे बचें?सी मैक्रो के मूल्य से चार स्ट्रिंग कैसे बनाएं?

#ifndef TEST_FUN 
# define TEST_FUN func_name 
# define TEST_FUN_NAME "func_name" 
#endif 

मैं Single Point of Truth नियम का पालन करना चाहता हूं। सी पूर्वप्रक्रमक की

संस्करण:

$ cpp --version 
cpp (GCC) 4.1.2 20070626 (Red Hat 4.1.2-14) 
+0

की संभावित डुप्लिकेट [सी मैक्रो तार बनाने के लिए] (http://stackoverflow.com/questions/798221/c-macros -to-create-strings) – rjstelling

उत्तर

67

He who is Shy* ने आपको answer का रोगाणु दिया, लेकिन केवल रोगाणु। सी पूर्व प्रोसेसर में एक स्ट्रिंग में कोई मान परिवर्तित करने के लिए बुनियादी तकनीक '#' ऑपरेटर के माध्यम से वास्तव में है, लेकिन प्रस्तावित समाधान का एक सरल लिप्यंतरण एक संकलन त्रुटि हो जाता है:

#define TEST_FUNC test_func 
#define TEST_FUNC_NAME #TEST_FUNC 

#include <stdio.h> 
int main(void) 
{ 
    puts(TEST_FUNC_NAME); 
    return(0); 
} 

सिंटेक्स त्रुटि पर है 'puts()' रेखा - समस्या स्रोत में 'stray #' है।

सी मानक की धारा 6.10.3.2 में, '# ऑपरेटर', यह कहते हैं:

Each # preprocessing token in the replacement list for a function-like macro shall be followed by a parameter as the next preprocessing token in the replacement list.

मुसीबत यह है कि आप तार करने के लिए मैक्रो तर्क में बदल सकते हैं - लेकिन आप यादृच्छिक परिवर्तित नहीं कर सकते वे आइटम जो मैक्रो तर्क नहीं हैं।

तो, आपके बाद के प्रभाव को प्राप्त करने के लिए, आपको निश्चित रूप से कुछ अतिरिक्त कार्य करना होगा।

#define FUNCTION_NAME(name) #name 
#define TEST_FUNC_NAME FUNCTION_NAME(test_func) 

#include <stdio.h> 

int main(void) 
{ 
    puts(TEST_FUNC_NAME); 
    return(0); 
} 

मैं कैसे आप मैक्रो का उपयोग करने की योजना पर पूरी तरह से स्पष्ट नहीं कर रहा हूँ, और आप कैसे पुनरावृत्ति पूरी तरह से बचने के लिए योजना है। यह थोड़ा अधिक विस्तृत उदाहरण अधिक जानकारीपूर्ण हो सकता है। STR_VALUE के समतुल्य मैक्रो का उपयोग एक मुहावरे है जो वांछित परिणाम प्राप्त करने के लिए आवश्यक है।

#define STR_VALUE(arg)  #arg 
#define FUNCTION_NAME(name) STR_VALUE(name) 

#define TEST_FUNC  test_func 
#define TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC) 

#include <stdio.h> 

static void TEST_FUNC(void) 
{ 
    printf("In function %s\n", TEST_FUNC_NAME); 
} 

int main(void) 
{ 
    puts(TEST_FUNC_NAME); 
    TEST_FUNC(); 
    return(0); 
} 

* समय था जब इस उत्तर पहले लिखा गया, shoosh नाम के हिस्से के रूप के नाम का इस्तेमाल किया 'शर्मीली'।

+0

यह काम करता है।धन्यवाद। मैंने एक कामकाजी उदाहरण पोस्ट किया है जो कोड के लिए प्रेरणा को दर्शाता है। http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-ac-macros-value#196093 – jfs

+0

मूल रूप से बनाई गई टिप्पणी का लगभग वर्बैटिम पुनर्लेखन 2012-10-12 21:37 (जो '__func__' के बजाय एक बोल्ड __func__ दिखाता है) - बेशक, सी 99 में, हम फंक्शन नाम के अर्थ में '__func__' प्री-डिफ़ाइंड पहचानकर्ता का उपयोग कर सकते हैं। हालांकि, यह फ़ंक्शन के बाहर कोई मदद नहीं है, और यही वह जगह है जहां फ़ंक्शन नाम स्ट्रिंग की वास्तव में आवश्यकता है। –

+0

आपका दूसरा कोड मेरे लिए काम नहीं करता है। ओपी के मामले के लिए 'test_func' एक मैक्रो होना चाहिए जो मुझे लगता है। यदि आप #define test_func my_test_func डालते हैं। (इस प्रकार test_func एक मैक्रो बना रहा है), यह अभी भी 'test_func' प्रिंट करता है 'my_test_func' नहीं। –

-2

#define TEST_FUN_NAME #FUNC_NAME

देख here

+2

यह काम नहीं करता है। मेरा जवाब देखें – jfs

+2

यह वास्तव में गलत है - मेरा जवाब भी देखें। यह भी आश्चर्यजनक है कि इसमें 4 वोट हैं। परेशानी यह है कि ऐसा लगता है कि अगर आप ध्यान से नहीं सोच रहे हैं तो यह कम या ज्यादा सही हो सकता है। –

0
#include <stdio.h> 

#define QUOTEME(x) #x 

#ifndef TEST_FUN 
# define TEST_FUN func_name 
# define TEST_FUN_NAME QUOTEME(TEST_FUN) 
#endif 

int main(void) 
{ 
    puts(TEST_FUN_NAME); 
    return 0; 
} 

संदर्भ: विकिपीडिया के C preprocessor पेज

+1

यह या तो काम नहीं करता है। मेरा जवाब देखें – jfs

12

@ जोनाथन लेफ्लर: धन्यवाद। आपका समाधान काम करता है।

एक पूरा काम कर उदाहरण:

/** compile-time dispatch 

    $ gcc -Wall -DTEST_FUN=another_func macro_sub.c -o macro_sub && ./macro_sub 
*/ 
#include <stdio.h> 

#define QUOTE(name) #name 
#define STR(macro) QUOTE(macro) 

#ifndef TEST_FUN 
# define TEST_FUN some_func 
#endif 

#define TEST_FUN_NAME STR(TEST_FUN) 

void some_func(void) 
{ 
    printf("some_func() called\n"); 
} 

void another_func(void) 
{ 
    printf("do something else\n"); 
} 

int main(void) 
{ 
    TEST_FUN(); 
    printf("TEST_FUN_NAME=%s\n", TEST_FUN_NAME); 
    return 0; 
} 

उदाहरण:

$ gcc -Wall -DTEST_FUN=another_func macro_sub.c -o macro_sub && ./macro_sub 
do something else 
TEST_FUN_NAME=another_func