2015-06-29 14 views
6

दूसरे दिन मैंने CodeReview पर एक पोस्ट बनाया। एक व्यक्ति जिसने मेरे प्रश्न का उत्तर दिया है, सुझाव दिया है कि मैं strcasecmp() का उपयोग करने से बचना चाहता हूं क्योंकि "फ़ंक्शन गैर मानक [और] यह [मेरा] कोड गैर-पोर्टेबल बनाता है।")strcasecmp(): एक गैर मानक समारोह?

int playGame() 
{ 

    char scanned[3]; 
    printf("Do you wish to play tick-tack-toe?\n"); 
    scanf("%s", scanned); 
    if(strcasecmp(scanned,"yes")==0) 
     startGame(); 

    else 
    { 
     if (strcasecmp(scanned,"no")==0 || strcasecmp(scanned,"nah")==0 || strcasecmp(scanned,"naw")==0) 
     { 
      printf("That's too bad!/nThis program will now end."); 
      return 1; 
     } 
     printf("Not valid input!/nThis program will now end."); 
     return 1; 
    } 
return 0; 
} 

किसी में गहराई से अधिक है और क्यों strcasecmp (व्याख्या कर सकते हैं इन सीमाएँ हैं: यह मैं इसे कैसे इस्तेमाल किया है?

+1

क्यों न केवल [मानक] (http://port70.net/~nsz/c/c11/n1570.html) देखें? – Olaf

+1

लेकिन मानक "मानक" कौन सा मानक है? मानकों के बारे में महान बात यह है कि उनमें से बहुत सारे हैं! वास्तव में, strcasecmp फ़ंक्शन बीएसडी/पॉज़िक्स में libc मानक लाइब्रेरी में परिभाषित किया गया है। –

+0

व्यक्तिगत रूप से, मैं सिर्फ यह जांचूंगा कि पहला अक्षर 'एन' या 'एन' है और इसे एक दिन कॉल करें, बदले के विशिष्ट उदाहरणों के लिए खाते की कोशिश करने की बजाय। लेकिन यहां हम मानव-जेनरेट किए गए टेक्स्ट इनपुट को पार्स करने की कोशिश कर रहे कंप्यूटरों की एक बड़ी समस्या पर सीमा रखते हैं। –

उत्तर

3

strcasecmp सी या सी ++ मानक में नहीं है। यह POSIX.1-2001 और 4.4BSD द्वारा परिभाषित किया गया है।

यदि आपका सिस्टम पॉज़िक्स या बीएसडी अनुपालन करता है, तो आपको कोई समस्या नहीं होगी। अन्यथा, समारोह अनुपलब्ध होगा।

+0

आगे, 'strcasecmp() 'के लिए एक और पोर्टेबल विकल्प नहीं है; आपको कुछ प्लेटफॉर्म पर 'stricmp() 'उपलब्ध हो सकता है, लेकिन यह भी बहुत मानक नहीं है। यदि आपको पोर्टेबल होने के लिए कोड की आवश्यकता है, तो केस-असंवेदनशील तुलना करने के लिए अपना स्वयं का फ़ंक्शन लिखें। ध्यान दें कि 'str' से शुरू होने वाले नाम निम्न-केस अक्षर के बाद सी मानक द्वारा आरक्षित हैं। –

+0

क्या इसका मतलब यह है कि strcmp() भी गैर-मानक है? "ध्यान दें कि निम्न-केस अक्षर के बाद str शुरू करने वाले नाम सी मानक द्वारा आरक्षित हैं।" क्या आपका मतलब नहीं है? क्योंकि strcasecmp() "str" ​​से शुरू होता है और उसके बाद निम्न-केस अक्षर होता है। – SuperGoA

+1

यह एक पूर्ण गलत व्याख्या है। ध्यान से पढ़ें: "निम्न-केस पत्र के बाद स्ट्र के साथ शुरू होने वाले नाम सी मानक द्वारा आरक्षित हैं"। इसका मतलब है कि _you_ स्ट्रैसव्यू नामक एक फ़ंक्शन लिखें, फिर _you_ ने सी मानक छोड़ दिया है। strcmp सी मानक का _part_ है। – gnasher729

1

"फ़ंक्शन गैर मानक" का अर्थ है कि फ़ंक्शन घोषणा और अनुबंध सी अंतर्राष्ट्रीय मानक में निर्दिष्ट नहीं हैं।

"यह कोड गैर पोर्टेबल बनाता है" का अर्थ है कि कार्यान्वयन को strcasecmp() लागू करने की आवश्यकता नहीं है, और इसलिए आपका कोड पूरी तरह से मानक-अनुरूप नहीं है और सख्ती से मानक-अनुरूप कंपिलरों द्वारा संकलित होने की गारंटी नहीं है।

strcasecmp() ही POSIX.1-2001 और 4.4BSD विनिर्देशों (link) का एक हिस्सा है।

+0

मुझे खेद है, लेकिन मुझे यह समझ में नहीं आता है: "यह कोड को गैर-पोर्टेबल माध्यम बनाता है, कि strcasecmp() को कार्यान्वित करने के लिए कार्यान्वयन की आवश्यकता नहीं है ..." स्ट्रसेकेकंप() गैर- -मानक। यह पहला जवाब के आधार पर लगता है कि काम के लिए कुछ 'विशेष' (POSIX.1-2001 या 4.4BSD) की आवश्यकता है। – SuperGoA

+1

उसका मतलब है कि, यदि समारोह सी मानक का हिस्सा नहीं है, तो एक सी संकलक जो मानक के अनुरूप है उसे लागू करने की आवश्यकता नहीं है। तो आपका कोड दुनिया में हर "मानक" सी संकलक पर संकलित नहीं हो सकता है। –

+1

@ सुपरगो अंतर्राष्ट्रीय सी मानक एक सिंगल दस्तावेज़ के रूप में आता है और सचमुच सबकुछ बताता है कि एक मानक-अनुरूप सी संकलक होना चाहिए/नहीं कर सकता/नहीं कर सकता/नहीं करना चाहिए। एक सख्ती से अनुरूप सी संकलक मानक से केवल चीजों को लागू करेगा। 'POSIX', मानक का हिस्सा नहीं है, बल्कि व्यापक रूप से स्वीकार्य विस्तार (विनिर्देश) है। अधिकांश विंडोज़ पर यह बस लागू नहीं किया गया है। –

0

संक्षिप्त उत्तर: strcasecmp() सी मानक में नहीं है, जो इसे गैर-मानक बनाता है।

strcasecmp() 4.4BSD, POSIX.1-2001 जैसे लोकप्रिय मानकों में परिभाषित किया गया है।

केस-कम फ़ंक्शंस की परिभाषा नाइट-पिक्य विवरणों का द्वार खोलती है। इन्हें ओपी द्वारा उपयोग किए जाने वाले 0 या non-0 के मामले में कम-से-कम तुलनाओं के परिणामस्वरूप + या - शामिल होते हैं। विशेष रूप से:

पॉज़िक्स लोकेल में, strcasecmp() और strncasecmp() व्यवहार करेंगे जैसे स्ट्रिंग को लोअरकेस में परिवर्तित कर दिया गया था और फिर बाइट तुलना की गई थी। परिणाम अन्य लोकेशंस में निर्दिष्ट नहीं हैं।

इसके साथ समस्या ऊपरी और निचले केस अक्षरों के साथ है जिसमें 1 से 1 मैपिंग नहीं है। एक स्थानीय पर विचार करें जिसमें E, e और é लेकिन É, अभी तक toupper('é') ->'E' है। फिर "जैसे तारों को लोअरकेस में परिवर्तित कर दिया गया था" के साथ, 'E' में 2 विकल्प हैं।

int SGA_stricmp(const char *a, const char *b) { 
    int ca, cb; 
    do { 
    ca = (unsigned char) *a++; 
    cb = (unsigned char) *b++; 
    ca = tolower(toupper(ca)); 
    cb = tolower(toupper(cb)); 
    } while (ca == cb && ca != '\0'); 
    return ca - cb; 
} 

आप राउंड ट्रिप के लिए नहीं करना चाहते हैं:

एक candidate पोर्टेबल समाधान के रूप में उस दौर पर विचार गैर 1 से 1 मैपिंग से निपटने के लिए (ऊपरी तो कम करने के लिए करने के लिए) पत्र यात्राएं मान का उपयोग करें:

 ca = tolower(ca); 
    cb = tolower(cb); 

विवरण: toupper() और tolower() केवल unsigned char और EOF की रेंज में int के लिए परिभाषित किया।

-1

वैकल्पिक विकल्प है जो टोलर() का उपयोग करके कम मामले में इनपुट को कैनन करना होगा। फिर आप मानक strcmp() का उपयोग कर सकते हैं।

+0

ध्यान दें कि यह 'strcasecmp() 'से कार्यात्मक रूप से भिन्न हो सकता है जब ऊपरी/निचले केस अक्षरों में 1-से-1 मैपिंग नहीं होती है। यह 'strcasecmp()' विनिर्देशों पर निर्भर करता है (यह सी मानक नहीं है)। अधिकांश 'strcasecmp()' डिफ़ॉल्ट लोकेल के लिए इस 'tolower() 'दृष्टिकोण का उपयोग करते हैं। – chux

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