दिलचस्प पोस्ट
SQL सर्वर में विदेशी कुंजी निर्भरता कैसे प्राप्त करें? सी # बाइनरी लीटरल बल लेआउट के प्रारंभिक टिक को शांत करें INSERT पर SQL इंजेक्शन कैसे कोणीय यहाँ क्षेत्र के साथ अद्यतन नहीं करता है? एंड्रॉइड 1.5: एसएमएस संदेश पढ़ना डेटाबेस में आप प्रभावशाली मॉडल कैसे प्राप्त कर सकते हैं? ToList () को कॉल करते समय क्या कोई प्रभाव पड़ता है? सेलेनियम चेकबॉक्स विशेषता "चेक" जेवीग्रीड पर वर्ड वर्प को कैसे कार्यान्वित करें जो आईई 7, आईई 8 और एफएफ पर काम करता है स्विफ्ट – डाउनलोड टास्क विथ url के साथ वीडियो डाउनलोड करना php में mysql की तालिका से गिनती (*) का चयन करें Google चार्ट में एसटीवीजी के अंदर छवियों के साथ मैं पीएनजी (बेस 64) कैसे प्राप्त कर सकता हूं? PyQt4.QtGui आयात नहीं किया जा सकता सी या सी ++ में गैर रिक्त निर्देशिका प्रोग्राम को हटाना

तार बनाने के लिए सी मैक्रोज़

वैकल्पिक शीर्षक (खोज सहायता)

  • एक स्ट्रिंग में एक प्रीप्रोसेसर टोकन कन्वर्ट करें
  • कैसे एक सी मैक्रो के मूल्य से एक चार तार बनाने के लिए?

मूल प्रश्न

मैं समय को संकलित करने के लिए शाब्दिक स्ट्रिंग बनाने के लिए सी #define का उपयोग करना चाहूंगा

स्ट्रिंग डोमेन है जो डीबग, रिलीज़ आदि के लिए बदलता है।

मैं कुछ इस तरह से कुछ करना चाहूंगा:

 #ifdef __TESTING #define IV_DOMAIN domain.org //in house testing #elif __LIVE_TESTING #define IV_DOMAIN test.domain.com //live testing servers #else #define IV_DOMAIN domain.com //production #endif // Sub-Domain #define IV_SECURE "secure.IV_DOMAIN" //secure.domain.org etc #define IV_MOBILE "m.IV_DOMAIN" 

लेकिन पूर्वप्रक्रमक "" के भीतर कुछ भी मूल्यांकन नहीं करता है

  1. क्या इसके चारों ओर एक रास्ता है?
  2. क्या यह भी एक अच्छा विचार है?

Solutions Collecting From Web of "तार बनाने के लिए सी मैक्रोज़"

सी में, स्ट्रिंग लीटरल को स्वचालित रूप से जोड़ दिया जाता है उदाहरण के लिए,

 const char * s1 = "foo" "bar"; const char * s2 = "foobar"; 

s1 और s2 समान स्ट्रिंग हैं

इसलिए, आपकी समस्या के लिए, उत्तर (टोकन चिपकाने के बिना) है

 #ifdef __TESTING #define IV_DOMAIN "domain.org" #elif __LIVE_TESTING #define IV_DOMAIN "test.domain.com" #else #define IV_DOMAIN "domain.com" #endif #define IV_SECURE "secure." IV_DOMAIN #define IV_MOBILE "m." IV_DOMAIN 

ऐसा करने के दो तरीके हैं:

  1. अगर आप केवल स्ट्रिंग लीटरल से काम कर रहे हैं, तो आप बस स्ट्रिंग्स का उपयोग कर सकते हैं – एक स्ट्रिंग को शाब्दिक रखने के बाद दूसरे को कंपाइलर को जोड़ने के लिए इसका कारण बनता है

  2. अगर स्ट्रिंग लीटरल से जुड़े अन्य चीजें हो सकती हैं (यानी, आप मैक्रो से नए आइडेंटिफ़ायर बना रहे हैं) ' ## ' प्रीप्रोसेसर टोकन पेस्टिंग ऑपरेटर का उपयोग करें। शायद आपको ' # ' स्ट्रिंगिंग ऑपरेटर का इस्तेमाल करना होगा अपने मैक्रो को शाब्दिक तारों में बनायें

# 1 का एक उदाहरण:

 #ifdef __TESTING #define IV_DOMAIN "domain.org" //in house testing #elif __LIVE_TESTING #define IV_DOMAIN "test.domain.com" //live testing servers #else #define IV_DOMAIN "domain.com" //production #endif // Sub-Domain #define IV_SECURE "secure." IV_DOMAIN //secure.domain.org etc #define IV_MOBILE "m." IV_DOMAIN 

और जहां तक ​​टोकन पेस्ट ऑपरेटर चला जाता है, मुझे नहीं लगता है कि टोकन पेस्टिंग प्रीप्रोसेसर ऑपरेटर का उपयोग करने का सुझाव देने वाले अधिकांश उत्तर ने वास्तव में इसे करने की कोशिश की है – यह उपयोग करने के लिए मुश्किल हो सकता है

अक्सर सुझाव दिया जाता है कि उत्तर का उपयोग करते हुए आप IV_SECURE मैक्रो का उपयोग करने की कोशिश करते समय एक कंपाइलर त्रुटि का कारण IV_SECURE , क्योंकि:

 #define IV_SECURE "secure."##IV_DOMAIN 

फैलता है:

 "secure"domain.org 

आप ' #' स्ट्रिंगिंग ऑपरेटर का उपयोग करने की कोशिश करना चाहेंगे:

 #define IV_SECURE "secure." #IV_DOMAIN 

लेकिन यह काम नहीं करेगा क्योंकि यह केवल मैक्रो तर्क पर काम करता है – न सिर्फ किसी भी पुराने मैक्रो।

जब आप टोकन-पेस्ट ('##') या स्ट्रिंगिंग ('#') प्रीप्रोसिटिंग ऑपरेटर्स का उपयोग कर रहे हैं, तो एक बात यह है कि आपको सभी मामलों में ठीक से काम करने के लिए उनके लिए एक अतिरिक्त स्तर का संकेत देना होगा।

यदि आप ऐसा नहीं करते हैं और टोकन-पेस्टिंग ऑपरेटर को पास किए गए आइटम मैक्रोज़ स्वयं होते हैं, तो आपको ऐसे परिणाम मिलते हैं जो संभवतः आप नहीं चाहते हैं:

 #include <stdio.h> #define STRINGIFY2( x) #x #define STRINGIFY(x) STRINGIFY2(x) #define PASTE2( a, b) a##b #define PASTE( a, b) PASTE2( a, b) #define BAD_PASTE(x,y) x##y #define BAD_STRINGIFY(x) #x #define SOME_MACRO function_name int main() { printf( "buggy results:\n"); printf( "%s\n", STRINGIFY( BAD_PASTE( SOME_MACRO, __LINE__))); printf( "%s\n", BAD_STRINGIFY( BAD_PASTE( SOME_MACRO, __LINE__))); printf( "%s\n", BAD_STRINGIFY( PASTE( SOME_MACRO, __LINE__))); printf( "\n" "desired result:\n"); printf( "%s\n", STRINGIFY( PASTE( SOME_MACRO, __LINE__))); } 

उत्पादन:

 buggy results: SOME_MACRO__LINE__ BAD_PASTE( SOME_MACRO, __LINE__) PASTE( SOME_MACRO, __LINE__) desired result: function_name21 

तो अपने मूल IV_DOMAIN परिभाषित करता है और उपरोक्त उपयोग मैक्रोज़ का उपयोग करके, आप ऐसा कर सकते हैं जो आप चाहते हैं:

 // Sub-Domain #define IV_SECURE "secure." STRINGIFY( IV_DOMAIN) //secure.domain.org etc #define IV_MOBILE "m." STRINGIFY( IV_DOMAIN) 

स्ट्रिंग्स जो अगले साथ हैं, सी संकलक द्वारा संयोजित की जाती हैं।

 #define DOMAIN "example.com" #define SUBDOMAIN "test." DOMAIN const char *asCString = SUBDOMAIN; NSString *asNSString = @SUBDOMAIN; 

## ऑपरेटर का उपयोग करने का प्रयास करें

 #define IV_SECURE secure.##IV_DOMAIN 

मैं आपके पहले प्रश्न के बहुत सारे अच्छे और सही उत्तर देखता हूं, लेकिन आपके दूसरे के लिए कोई नहीं, इसलिए ये है: मुझे लगता है कि यह एक भयानक विचार है सर्वर सॉफ्टवेयर को बदलने के लिए आपको अपने सॉफ़्टवेयर (विशेषकर रिलीज़ संस्करण) को क्यों पुनर्निर्माण करना चाहिए? साथ ही, आप कैसे जानते होंगे कि किस सॉफ़्टवेयर के कौन से संस्करण को सर्वर पर दिया गया है? रनटाइम पर जांच करने के लिए आपको एक तंत्र में निर्माण करना होगा। यदि यह आपके प्लेटफ़ॉर्म पर व्यावहारिक है, तो मैं आपको एक config फ़ाइल से डोमेन / यूआरएल लोड करने की सलाह देता है। केवल वांछित एम्बेडेड प्लेटफ़ॉर्म, उस उद्देश्य के लिए "व्यावहारिक" नहीं हो सकता है 🙂

आपको क्या जरूरत है # और ## ऑपरेटर्स, और स्वत: स्ट्रिंग कन्टेनटेनेशन

# प्रीप्रोसेटिंग ऑपरेटर मैक्रो पैरामीटर को स्ट्रिंग में बदल देता है। ## ऑपरेटर दो टोकन (जैसे मैक्रो पैरामीटर) को एक साथ चिपकाता है।

संभावना है कि मेरे मन में आता है

 #define IV_DOMAIN domain.org #define IV_SECURE(DOMAIN) "secure." #DOMAIN 

जिसे IV_SECURE को बदलना चाहिए

 #define IV_SECURE "secure." "domain.org" 

जो स्वचालित रूप से "secure.domain.org" से जुड़ा होगा (अनुवाद के चरणों को संभालने के लिए सी में समान है C ++)।

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

जैसा कि अन्य लोगों ने नोट किया है, टोकन चिपकाने का उपयोग करें आपको यह भी अवगत होना चाहिए कि मैक्रो नाम जैसे जैसे

 __TESTING 

कार्यान्वयन के लिए सी में आरक्षित हैं (उद्देश्य सी के बारे में नहीं पता है) – आपको अपने कोड में उनका उपयोग करने की अनुमति नहीं है आरक्षित नाम कुछ भी होते हैं जिन पर डबल अंडरस्कोर होते हैं और कुछ अंडरस्कोर और एक अपरकेस अक्षर के साथ शुरू होते हैं।