2012-09-17 32 views
9

मान लीजिए कि मैं strtok() इस तरह उपयोग कर रहा हूँ चलो ..सी - निर्धारण जो सीमांकक इस्तेमाल किया - strtok()

char *token = strtok(input, ";-/"); 

वहाँ जो टोकन वास्तव में इस्तेमाल किया जाता है यह पता लगाने के लिए एक रास्ता है? उदाहरण के लिए, यदि आदानों की तरह कुछ था:

Hello there; How are you?/I'm good - End

मैं यह पता लगाने कर सकते हैं जो सीमांकक प्रत्येक टोकन के लिए इस्तेमाल किया गया था? टोकन के बाद वाले डेलीमीटर के आधार पर, मुझे एक विशिष्ट संदेश आउटपुट करने में सक्षम होना चाहिए।

+1

जानकारी के लिए, जब आप आदमी strtok: इस इंटरफ़ेस strsep द्वारा अप्रयुक्त है (3)। – Geoffroy

+0

नहीं, लेकिन यदि आप एक ऐसा संस्करण पूछने के लिए कोई प्रश्न पूछते हैं जो कोई करता है, तो कोई व्यक्ति लिख सकता है। char * strtok_new (char * string, const char * delimiters, char * मिलान); – Scooter

+0

ध्यान दें कि 'strsep' सी या पॉज़िक्स में नहीं है (हालांकि' strtok_r' पॉज़िक्स में है और 'strtok_s' सी 11 में है), लेकिन यह एलएसबी और बीएसडी में है। इसलिए 'स्ट्रेटोक' को कुछ सिस्टमों पर 'स्ट्रसेप' द्वारा अप्रचलित किया जाता है, न कि अन्य। मैन पेजों के बारे में बात यह है कि वे केवल उस सिस्टम पर लागू होते हैं जब आप 'मैन' चलाते हैं। –

उत्तर

8

महत्वपूर्ण: strtok फिर से प्रवेशी नहीं है, आप इसे करने के बजाय strtok_r उपयोग करना चाहिए।

आप मूल स्ट्रिंग की एक प्रति की बचत, और कहा कि कॉपी में वर्तमान टोकन के ऑफसेट में देख कर ऐसा कर सकते हैं:

char str[] = "Hello there; How are you?/I'm good - End"; 
char *copy = strdup(str); 
char *delim = ";-/"; 
char *res = strtok(str, delim); 
while (res) { 
    printf("%c\n", copy[res-str+strlen(res)]); 
    res = strtok(NULL, delim); 
} 
free(copy); 

यह प्रिंट

; 
/
- 

Demo #1

संपादित करें:एकाधिक डिलीमीटरों को संभालना

यदि आपको कई डिलीमीटरों को संभालने की आवश्यकता है, तो डिलीमीटरों के वर्तमान अनुक्रम की लंबाई निर्धारित करना थोड़ा कठिन हो जाता है: अब आपको निर्णय लेने से पहले अगला टोकन ढूंढना होगा कि डिलीमीटरों का अनुक्रम कितना समय है।गणित जटिल नहीं है, जब तक आप याद के रूप में है कि NULL विशेष उपचार की आवश्यकता है:

char str[] = "(20*(5+(7*2)))+((2+8)*(3+6*9))"; 
char *copy = strdup(str); 
char *delim = "*+()"; 
char *res = strtok(str, delim); 
while (res) { 
    int from = res-str+strlen(res); 
    res = strtok(NULL, delim); 
    int to = res != NULL ? res-str : strlen(copy); 
    printf("%.*s\n", to-from, copy+from); 
} 
free(copy); 

Demo #2

+0

धन्यवाद, यह वही व्यवहार है जिसे मैं प्राप्त करने की उम्मीद कर रहा था। –

+0

@dasblinkenlight, अगर आपके उत्तराधिकार में एकाधिक विभाजक हैं तो यह काम नहीं करेगा। उदाहरण के लिए अंकगणितीय अभिव्यक्ति 20 * 5 + (7 * 2) के टोकननाइजेशन पर विचार करें जहां आप अपना delim "+ -/*()" के रूप में परिभाषित करते हैं और आप ऑपरेटर और ऑपरेटरों के टोकननाइज़ेशन में रूचि रखते हैं। + (सही ढंग से टोकननाइज्ड नहीं किया जाएगा। – David

+1

@ डेविड आप सही हैं, कोड मानता है कि हमेशा एक डिलीमीटर होता है। हालांकि, इसके लिए एक आसान फिक्स है - आपको बस इतना करना है कि अगले टोकन को यह तय करने के लिए कि कितना समय है delimiters का वर्तमान भाग (संपादन और डेमो देखें) – dasblinkenlight

3

आप नहीं कर सकते। strtok अगले विभाजक चरित्र को एक नल चरित्र के साथ ओवरराइट करता है (इस टोकन को समाप्त करने के लिए टोकन को समाप्त करने के लिए), और यह पिछले मान को संग्रहीत नहीं करता है जो इसे ओवरराइट करता है। पहली बार जब आप अपनी उदाहरण स्ट्रिंग पर strtok पर कॉल करते हैं, तो ; हमेशा के लिए चला जाता है।

यदि आप strtok के साथ संशोधित स्ट्रिंग की एक अनमोल प्रतिलिपि रखते हैं तो आप कुछ कर सकते हैं - आपके वर्तमान टोकन (स्ट्रिंग की शुरुआत के सापेक्ष) के लिए नल टर्मिनेटर की अनुक्रमणिका दी गई है, तो आप देख सकते हैं प्रतिलिपि में एक ही सूचकांक और देखें कि वहां क्या था।

यह निश्चित रूप से स्ट्रिंग को अलग करने के लिए अपना स्वयं का कोड लिखने से भी बदतर हो सकता है। आप strpbrk या strcspn का उपयोग कर सकते हैं, यदि आप परिणामी टोकन के साथ रह सकते हैं जो आपके लिए नॉन-टर्मिनेटेड नहीं है।

1

आदमी 3 strtok

strtok() और strtok_r() फ़ंक्शन प्रत्येक अनुवर्ती टोकन के शुरुआत करने के लिए एक सूचक स्ट्रिंग, एक NUL चरित्र के साथ टोकन ही प्रतिस्थापित करने के बाद लौट आते हैं। जब अधिक टोकन रहते हैं, तो एक शून्य सूचक वापस आ जाता है।

लेकिन एक छोटे सूचक अंकगणित आप की तरह कुछ कर सकते हैं साथ:

char* string = "Hello,World!"; 
char* dup = strdup(string); 

char* world = strtok(string, ","); 
char delim_used = dup[world - string]; 

free(dup);