2009-02-27 4 views
11

जब मैं सी स्ट्रिंग के लिए एक कॉल इस तरह समारोह की तुलना करें:strcmp() वापस 0 देता है जब इसके इनपुट बराबर होते हैं?

strcmp("time","time")

यह 0 देता है, जिसका मतलब है कि तार बराबर नहीं हैं।

क्या कोई मुझे बता सकता है कि सी कार्यान्वयन ऐसा क्यों प्रतीत होता है? मुझे लगता है कि बराबर होने पर यह एक गैर-शून्य मान वापस करेगा। मैं इस व्यवहार को देख रहे कारणों से उत्सुक हूं।

+0

समय = पैसे सीधे - आपको पहले एक इकाई रूपांतरण को रोजगार के लिए है!। –

+4

जो भी इस स्पैम प्रश्न को नए लोगों के लिए संभावित रूप से उपयोगी बनाने में मदद करता है। मैं अभी भी इसके लिए मतदान करने को तैयार नहीं हूं, फिर भी यह ओपी को इस तरह के ट्रिप को दोबारा पोस्ट करने के लिए प्रोत्साहित नहीं करता है। – rmeador

+3

@remeador: धन्यवाद, लेकिन ओपी का अपमान नहीं करते हैं। – GEOCHET

उत्तर

22

strcmp पैरामीटर के रूप में दिए गए दो तारों के बारे में एक व्याख्यात्मक अंतर देता है (या मुझे इसे "शॉर्ट सर्किट सीरियल बाइट तुलनित्र"? :-)) कहा जाना चाहिए। 0 का अर्थ है कि दोनों तार बराबर हैं

एक सकारात्मक मूल्य का अर्थ है कि एस 1 एक शब्दकोश में एस 2 के बाद होगा।

एक ऋणात्मक मान का अर्थ है कि एस 1 एक शब्दकोश में एस 2 से पहले होगा।

इसलिए "समय" और "धन" की तुलना करते समय आपका गैर-शून्य मान स्पष्ट रूप से अलग है, भले ही कोई कहता है कि समय पैसा है! :-)

+2

strcmp के बजाय गैर शून्य() एक शाब्दिक तुलना करना नहीं है, यह केवल प्रत्येक चरित्र के मूल्य की तुलना जब तक वहाँ एक अंतर है या दोनों तार समाप्त। – Ferruccio

+0

मैं कसम खाता हूँ सकता है मैं डॉक्स कि strcmp कहा() एक शाब्दिक तुलना करता है, लेकिन कुछ त्वरित Googling पता चलता है फारुशियो सही है पढ़ा है ...क्या यह किसी बिंदु पर बदल सकता है? – rmeador

+0

नहीं। हमेशा इस तरह :-) – Ferruccio

3

आप एक (काल्पनिक) की तरह काम करने के लिए strcmp चाहते हैं

int isEqual(const char *, const char *) 

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

इसके अलावा, मुझे लगता है एक आम कार्यान्वयन लग रहा है कि

तरह
int strcmp(const char *s1, const char *s2){ 
    const unsigned char *q1=s1, *q2=s2; 
    while ((*q1 == *q2) && *q1){ 
     ++q1; ++q2; 
    }; 
    return (*q1 - *q2); 
} 

है जो [संपादित करें: थोड़े] रास्ते से एक कश्मीर & आर वस्तु के रूप में सुरुचिपूर्ण। महत्वपूर्ण बात यहाँ (जो तेजी से कोड सही होने के कारण अस्पष्ट हो (जाहिर है मैं काफी अच्छी तरह से छोड़ दिया जाना चाहिए था अकेले)) जिस तरह से वापसी कथन है:

return (*q1 - *q2); 

जो तुलना के परिणामों के संदर्भ में स्वाभाविक रूप से देता है चरित्र मूल्य।

+0

नहीं है कि "आम कार्यान्वयन" बंद बफर पाश समाप्त करने के लिए चलना होगा (पिछले अशक्त समाप्ति?) मैं नहीं दिख रहा है कि यह कैसे कभी वापसी होगी 0 ... –

+0

मुझे लगता है कि यू होगा है यदि आप \ 0 के लिए आते हैं :) आपको भी * s1 - * s2 में अंडरफ्लो देखना होगा, इसलिए s1 = -127, s2 = 2 => ओओएस :) –

+0

@ डैनियल: उह। हाँ। क्षण जब मैं इसे ठीक करता हूं ... – dmckee

5

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

आपके मामले में, यदि स्ट्रिंग बराबर है, तो का कोई कारण नहीं है यह तार के समान वर्णों के बराबर है। लेकिन अगर वे गैर-बराबर हैं तो पहले या तो छोटा हो सकता है, या दूसरा छोटा हो सकता है। इसे 1 बराबर के लिए 1, छोटे के लिए 0 और अधिक के लिए 2 वापस करने के लिए मुझे लगता है कि किसी भी तरह अजीब होगा।

तुम भी घटाव के मामले में इसके बारे में सोचो कर सकते हैं:

return = s1 - s2 

तो एस 1 है "कोषगत" कम है, तो यह दे देंगे एक नकारात्मक मूल्य है।

+0

में यह लिख सकता है मैं बहुत यकीन है कि आप भिन्नता अपने के के की जरूरत है हूँ सकता है ... – dmckee

+0

मेरा मतलब यह प्रतीकात्मक था छद्म कोड। –

+0

आह। मैं सुझाव वापस लेता हूं। – dmckee

0

मुझे लगता है कि यह समरूपता के लिए बस है: -1 अगर कम है, बराबर यदि 0, 1, तो अधिक।

10

इस तरह एक कार्यान्वयन के बारे में अच्छी बात यह है कि आप कह सकते हैं

if(strcmp(<stringA>, <stringB>) > 0) // Implies stringA > stringB 
if(strcmp(<stringA>, <stringB>) == 0) // Implies stringA == stringB 
if(strcmp(<stringA>, <stringB>) < 0) // Implies stringA < stringB 
if(strcmp(<stringA>, <stringB>) >= 0) // Implies stringA >= stringB 
if(strcmp(<stringA>, <stringB>) <= 0) // Implies stringA <= stringB 
if(strcmp(<stringA>, <stringB>) != 0) // Implies stringA != stringB 

नोट कैसे 0 के साथ तुलना बिल्कुल निहितार्थ में तुलना से मेल खाता है।

+1

comp.lang.c FAQ से एक अद्भुत/भयानक मैक्रो है जो लगभग इस स्ट्रिंग व्यवहार को लागू करता है। '# डिफ़ॉल्ट रूप से परिभाषित करें (str1, op, str2) (strcmp (str1, str2) op 0) 'इसके साथ, आप' अगर (स्ट्रेटेस्ट (स्ट्रिंगए, ==, स्ट्रिंगबी)) 'और दोस्तों को लिखेंगे। मैं बाड़ पर हूं कि यह एक भयानक विचार है या एक अद्भुत विचार है। –

2

है तीन संभावित परिणाम: स्ट्रिंग 1 स्ट्रिंग 1, स्ट्रिंग 2 के बाद आता है स्ट्रिंग 1 एक ही स्ट्रिंग 2. के रूप में यह इन तीन परिणाम अलग रखने के लिए महत्वपूर्ण है, स्ट्रिंग 2 से पहले आता है, strcmp() का एक उपयोग तारों को सॉर्ट करना है। सवाल यह है कि आप इन तीन परिणामों के मूल्यों को कैसे आवंटित करना चाहते हैं, और चीजों को कम या कम कैसे बनाए रखना है। आप qsort() और bsearch() के पैरामीटर को भी देख सकते हैं, जिसके लिए स्ट्रैम्प() जैसे कार्यों की तुलना करने की आवश्यकता होती है।

आप एक स्ट्रिंग समानता समारोह चाहते थे, तो यह बराबर तार और शून्य गैर बराबर तार के लिए के लिए अशून्य वापसी होगी, सच्चे और झूठे पर सी के नियमों के साथ जाने के लिए। इसका मतलब यह है कि स्ट्रिंग 1 स्ट्रिंग 2 से पहले या उसके बाद आया था या नहीं। इस बात का कोई तरीका नहीं होगा कि एक int, या किसी अन्य सी डेटा प्रकार के लिए कई सत्य मान हैं जिन्हें आप नाम देना चाहते हैं, लेकिन केवल एक झूठी है।

इसलिए, एक उपयोगी strcmp() कि स्ट्रिंग समानता के लिए सच लौटे भाषा के आराम करने के परिवर्तन, जो बस होने के लिए नहीं जा रहे हैं की एक बहुत कुछ की आवश्यकता होगी है।

4

एक अन्य कारण strcmp() रिटर्न कोड यह, इतना है कि यह मानक पुस्तकालय समारोह qsort() में सीधे इस्तेमाल किया जा सकता है आप तार की एक सरणी सॉर्ट करने के लिए अनुमति देता है करता है:

#include <string.h> // for strcmp() 
#include <stdlib.h> // for qsort() 
#include <stdio.h> 

int sort_func(const void *a, const void *b) 
{ 
    const char **s1 = (const char **)a; 
    const char **s2 = (const char **)b; 
    return strcmp(*s1, *s2); 
} 

int main(int argc, char **argv) 
{ 
    int i; 
    printf("Pre-sort:\n"); 
    for(i = 1; i < argc; i++) 
     printf("Argument %i is %s\n", i, argv[i]); 
    qsort((void *)(argv + 1), argc - 1, sizeof(char *), sort_func); 
    printf("Post-sort:\n"); 
    for(i = 1; i < argc; i++) 
     printf("Argument %i is %s\n", i, argv[i]); 
    return 0; 
} 

इस छोटे नमूना कार्यक्रम अपने तर्कों पर क्रमबद्ध ASCIIBetically (कुछ क्या lexically कॉल करेंगे)। Lookie:

$ gcc -o sort sort.c 
$ ./sort hi there little fella 
Pre-sort: 
Argument 1 is hi 
Argument 2 is there 
Argument 3 is little 
Argument 4 is fella 
Post-sort: 
Argument 1 is fella 
Argument 2 is hi 
Argument 3 is little 
Argument 4 is there 

तो strcmp() लौटे 1 (सही) बराबर तार और 0 (गलत) inequal लोगों के लिए के लिए, यह इसका इस्तेमाल करने डिग्री प्राप्त करने के लिए असंभव हो जाएगा या दिशा असमानता के (यानी कैसे अलग-अलग, और कौन सा बड़ा है) दो तारों के बीच, इस प्रकार इसे सॉर्टिंग फ़ंक्शन के रूप में उपयोग करना असंभव बना देता है। सूचक अंकगणित, सूचक recasting, और समारोह संकेत - -

मैं नहीं जानता कि आप कोड ऊपर सी के साथ कैसे परिचित हैं सी के सबसे भ्रामक अवधारणाओं में से कुछ का उपयोग करता है ताकि आप उस कोड, डॉन के कुछ समझ में नहीं आता है, तो चिंता मत करो, आप समय पर वहां पहुंच जाएंगे। तब तक, आपके पास StackOverflow पर पूछने के लिए बहुत सारे मज़ेदार प्रश्न होंगे। ;)

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