2016-03-17 3 views
5

मैं अलग-अलग शब्दों में एक रेखा को पार्स करने के लिए strtok() का उपयोग कर रहा हूं और उन्हें कुछ के लिए जांच सकता हूं। यदि वह चीज़ मिलती है, तो एक और फ़ंक्शन कहा जाता है जिसे strtok() का भी उपयोग करना चाहिए।स्ट्रेटोक() का उपयोग दो कार्यों में सुरक्षित है?

मुझे पता है strtok() पुन: प्रवेश नहीं है। क्या इसका मतलब यह है कि अगर मैं इसे दूसरे फ़ंक्शन में कॉल करता हूं, तो पहले फ़ंक्शन में स्ट्रिंग में मेरी स्थिति खो जाएगी? यदि ऐसा है, तो पहले चरण में strtok() का उपयोग करेंगे और दूसरी समस्या में strtok_r() समस्या का समाधान होगा? क्या कोई और समाधान है?

संपादित करें: धन्यवाद। स्ट्रेटोक का उपयोग दो कार्यों में करना संभव नहीं है लेकिन स्पष्ट रूप से strtok_r मानक नहीं है। इसे फिर से डिजाइन करें ...

+5

हमेशा का उपयोग कर strtok_r सुरक्षित होना चाहिए जाने के लिए रास्ता। – mkiever

+2

@mkiever मुझे लगता है कि यह बहुत दुर्लभ है कि आपके पास strtok का उपयोग कर कई धागे हैं? एक गैर मानक कार्य वास्तव में क्यों जाना है, जब थ्रेड-सुरक्षा की आवश्यकता भी नहीं है? आप अपने प्रोग्राम को धीमा करना और इसे पोर्टेबल बनाना चाहते हैं। – Lundin

+0

@ लंदन गैर-मानक? http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtok.html – marcolz

उत्तर

0

Q1:

मतलब है कि कि अगर मैं दूसरे समारोह में इसे कहते पहले समारोह में स्ट्रिंग में मेरी स्थिति खो जाएगा?

ए 1: हाँ, यह करता है। यदि आप ऐसा करते हैं, तो आपके द्वारा प्रदान की गई दूसरी स्ट्रिंग के साथ एक नया स्कैनिंग अनुक्रम प्रारंभ किया जाएगा, और आपकी पहली स्ट्रिंग के लिए बाद की कॉल के डेटा खो जाएंगे।

Q2:

यदि हां, तो पहले समारोह और में strtok_r() में strtok() का उपयोग होता है दूसरी समस्या का समाधान?

ए 2: बेहतर तरीका आपके प्रोग्राम डिज़ाइन को पुन: कार्य करना होगा।

Q3:

वहाँ एक और समाधान है?

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

6

चूंकि strtok आंतरिक रूप से स्ट्रिंग में कितना उन्नत था, यह स्टोर करने के लिए एक वैश्विक चर का उपयोग करता है, strtok पर इंटरमलिंग कॉल विफल हो जाएगा, जैसा कि आपको संदेह है। आपके विकल्प हैं:

  • स्विच strtok_r, जो एक समान एपीआई है, लेकिन मानक सी (यह, POSIX में है, हालांकि) नहीं है करने के लिए;
  • strtok से बचने के लिए पूरी तरह से किसी अन्य फ़ंक्शन के पक्ष में जो strsep (गैर मानक भी) नहीं है;
  • सुनिश्चित करें कि आपका पहला फ़ंक्शन strtok को किसी अन्य फ़ंक्शन को कॉल करने से पहले strtok पर कॉल कर सकता है।

सभी में, strtok एक कार्य सर्वोत्तम से बचा है।

1

पुस्तकालय समारोह strtok वर्तमान पार्स स्थिति के लिए एक आंतरिक स्थिर राज्य का उपयोग करता है:

  • जब तार के साथ कहा जाता है, यह एक नया पार्स शुरू होता है,
  • जब पहली तर्क के रूप में NULL साथ कहा जाता है, इसे इस्तेमाल करता है इसकी आंतरिक स्थिति।

आप प्रत्यक्ष या परोक्ष रूप से अपने पार्स पाश से strtok कॉल करते हैं, आंतरिक स्थिति को अद्यतन किया जाएगा और बाहरी दायरे से NULL साथ कॉल पहले वाली स्थिति से जारी रखने के लिए नहीं होगा, संभवतः अपरिभाषित व्यवहार लागू।

पॉज़िक्स फ़ंक्शन strtok_r एक स्पष्ट राज्य तर्क लेता है, इसलिए इसे नेस्टेड संदर्भों में उपयोग किया जा सकता है। यदि यह फ़ंक्शन आपके सिस्टम पर उपलब्ध है, तो इसे उन सभी स्थानों पर उपयोग करें जहां आप strtok का उपयोग करते हैं। वैकल्पिक रूप से, आप strchr() या strcspn() के साथ एक अलग विधि कर सकते हैं।

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

char *strtok_r(char *s, const char *delim, char **context) { 
    char *token = NULL; 

    if (s == NULL) 
     s = *context; 

    /* skip initial delimiters */ 
    s += strspn(s, delim); 
    if (*s != '\0') { 
     /* we have a token */ 
     token = s; 
     /* skip the token */ 
     s += strcspn(s, delim); 
     if (*s != '\0') { 
      /* cut the string to terminate the token */ 
      *s++ = '\0'; 
     } 
    } 
    *context = s; 
    return token; 
} 
0

http://en.cppreference.com/w/c/string/byte/strtok वेबसाइट में संकेत के रूप में::

strtok को प्रत्येक कॉल एक स्थिर चर को संशोधित करता है: सुरक्षित थ्रेड नहीं है

यहाँ एक सरल कार्यान्वयन आप उपयोग ca है।

तो हाँ आप एक ही समय (सूत्रण) में दो अलग कार्यों से इस समारोह कॉल नहीं कर सकते और न ही आप इसे निम्नलिखित की तरह फोन नहीं कर सकते हैं:

char input[] = "something that needs to be tokenize"; 
char *token = strtok(input, " "); 
while(token) { 
    puts(token); 
    anotherfunction(); 
    token = strtok(NULL, " "); 
} 

void anotherfunction() 
{ 
    char input[] = "another string needs to be tokenize"; 
    char *tok = strtok(input, " "); 
    while(tok) { 
     puts(tok); 
     tok = strtok(NULL, " "); 
    } 
} 
संबंधित मुद्दे