2008-10-27 8 views
40

पर कनवर्ट करें मैं एक स्ट्रिंग में प्रीप्रोसेसर टोकन को कन्वर्ट करने का एक तरीका ढूंढ रहा हूं।एक प्रीप्रोसेसर टोकन को स्ट्रिंग

विशेष रूप से, मैंने कहीं मिल गया है:

#define MAX_LEN 16 

और मैं इसे उपयोग करने के लिए बफर सीमा से अधिक रोकना चाहते हैं:

char val[MAX_LEN+1]; // room for \0 
sscanf(buf, "%"MAX_LEN"s", val); 

मैं अन्य तरीकों से एक ही बात को पूरा करने के लिए खुला रहा हूँ, लेकिन केवल मानक पुस्तकालय।

+0

http://stackoverflow.com/questions/195975/how-to-make-a-char-string-from-ac-macros-value –

+0

स्ट्रिंग बनाने के लिए [सी मैक्रोज़ का संभावित डुप्लिकेट] (http: // स्टैक ओवरफ़्लो।कॉम/प्रश्न/798221/सी-मैक्रोज़-टू-बिल्ड-स्ट्रिंग्स) – rjstelling

उत्तर

78

विशेष रूप से http://www.decompile.com/cpp/faq/file_and_line_error_string.htm देखें:

#define STRINGIFY(x) #x 
#define TOSTRING(x) STRINGIFY(x) 
#define AT __FILE__ ":" TOSTRING(__LINE__) 

तो आपकी समस्या को हल किया जा सकता sscanf(buf, "%" TOSTRING(MAX_LEN) "s", val);

+0

क्यों 2 मैक्रोज़ कैस्केडिंग? पर्याप्त एक टॉर्चिंग नहीं होगा? –

+0

डबल-विस्तार स्ट्रिंगफिकेशन के बारे में नीचे उत्तर देखें। सी/सी ++ प्रीप्रोसेसर गंदा और बदसूरत है और मैं मानक के बिना विश्वास करता हूं। तो इसे एक के बजाय दो की आवश्यकता क्यों है, मैं नहीं कह सकता था, क्योंकि मैं शोध नहीं करना चाहता हूं। – Dan

+2

@ डैनियल ब्रूनर एक एकल मैक्रो टोकन को स्वयं पेस्ट करेगा, शाब्दिक रूप से '"% "" MAX_LEN ""% "' दूसरी "मैक्रो" टोकन * मान * चिपकाया जा सकता है, उदाहरण के लिए, '" 16 "' क्योंकि 'टॉस्ट्रिंग' 'मैक्रो अंतिम कोड को' STRINGIFY (16) 'के बराबर बनाता है। –

19

मुझे ऑनलाइन एक उत्तर मिला।

#define VERSION_MAJOR 4 
#define VERSION_MINOR 47 

#define VERSION_STRING "v" #VERSION_MAJOR "." #VERSION_MINOR 

से काम नहीं होता लेकिन उम्मीद है कि दिखाता है मुझे क्या करना, अर्थात VERSION_STRING रूप "v4.47" अंत करना चाहते हैं।

तरह

#define VERSION_MAJOR 4 
#define VERSION_MINOR 47 

#define STRINGIZE2(s) #s 
#define STRINGIZE(s) STRINGIZE2(s) 
#define VERSION_STRING "v" STRINGIZE(VERSION_MAJOR) \ 
"." STRINGIZE(VERSION_MINOR) 

#include <stdio.h> 
int main() { 
    printf ("%s\n", VERSION_STRING); 
    return 0; 
} 
+5

"STRINGIZE" भयानक लगता है .. – Blindy

4

यह एक समय हो गया है उचित अंकीय रूप उपयोग कुछ उत्पन्न करने के लिए है, लेकिन यह काम करना चाहिए:

sscanf(buf, "%" #MAX_LEN "s", val); 

यदि नहीं, तो यह करने की आवश्यकता होगी "डबल विस्तार" चाल:

#define STR1(x) #x 
#define STR(x) STR1(x) 
sscanf(buf, "%" STR(MAX_LEN) "s", val); 
+1

पहला काम नहीं करेगा; # मैक्रो विस्तार में मैक्रो तर्कों को स्ट्रिंग करता है। दूसरा काम करेगा। –

2

करके आप डबल विस्तार stringification मैक्रो चाल का उपयोग करना चाहिए। या बस

#define MAX_LEN 16 
#define MAX_LEN_S "16" 

char val[MAX_LEN+1]; 
sscanf(buf, "%"MAX_LEN_S"s", val); 

और इसे सिंक में रखें। (यह एक परेशानी का थोड़ा सा है, लेकिन जब तक परिभाषा एक-दूसरे के बगल में होती है, तो आपको शायद याद होगा।)

दरअसल, इस विशेष मामले में, strncpy पर्याप्त नहीं होगा?

strncpy(val, buf, MAX_LEN); 
val[MAX_LEN] = '\0'; 

यदि यह printf थे, हालांकि, यह आसान होगा:

sprintf(buf, "%.*s", MAX_LEN, val); 
+1

हाँ, मेरी इच्छा है कि * या कोई अन्य प्रतीक एक तर्क के साथ लंबाई-सीमित स्कैनफ रूटीन के लिए उपलब्ध था। उस फ़ॉर्म में sprintf strncpy, imo से बेहतर काम करता है, क्योंकि अगर यह बफर को ओवररन्स करता है तो strncpy स्ट्रिंग को समाप्त नहीं करेगा, और स्ट्रिंग बहुत छोटा होने पर अतिरिक्त डेटा लिखता है। – davenpcj

1

ऊपर "काम" के कुछ, व्यक्तिगत रूप से मैं बस के बजाय एक साधारण स्ट्रिंग एपीआई का उपयोग कर dreck की सलाह देते हैं जबकि वह libc में आता है। कई पोर्टेबल एपीआई हैं, जिनमें से कुछ को आपकी परियोजना में शामिल करने में आसानी के लिए भी अनुकूलित किया गया है ... और कुछ ustr जैसे छोटे स्पेस ओवरहेड और स्टैक वैरिएबल के लिए समर्थन है।

संबंधित मुद्दे