2012-12-29 3 views
10

मैं उन दोनों को समझने की कोशिश की लेकिन के लिए strcoll()this संदर्भ कहना है कि यहstrcmp() और strcoll() के बीच क्या अंतर है?

वर्तमान स्थान के अनुसार दो अशक्त समाप्त तार तुलना के रूप में LC_COLLATE श्रेणी के द्वारा परिभाषित मैं को छोड़कर किसी भी मतभेद नहीं मिला।

दूसरा विचार पर और मैं जानता हूँ कि मैं विस्तृत जवाब के लिए एक और सवाल पूछ रहा हूँ, वास्तव में दोनों C और C++ के लिए यह स्थान क्या है,?

+10

[यहाँ उदाहरण] (http://en.cppreference.com/w/cpp/string/बाइट/स्ट्रोकॉल) मेरी राय में बहुत स्पष्ट लगता है। – Rapptz

+0

@ रैपेटज़ ... ओह ... उस लिंक को देखना चाहिए .... पोस्ट करने से पहले ... – Recker

+0

hrnec chrt से पहले :) +1 – davak

उत्तर

25

strcmp() स्ट्रिंग के बाइट एक-एक करके लेता है और बाइट्स जो भी हो, उसकी तुलना करें।

strcoll() बाइट लेता है, उन्हें लोकेल का उपयोग करके बदलता है, फिर परिणाम की तुलना करता है। भाषा के आधार पर रूपांतरण पुन: आदेश। फ्रेंच में, accentuated पत्र गैर accentuated लोगों के बाद आते हैं। तो é के बाद है। हालांकि, éएफ से पहले है। strcoll() यह सही हो जाता है। strcmp() इतना अच्छा नहीं है।

हालांकि, कई मामलों में strcmp() पर्याप्त है क्योंकि आपको उपयोग में आने वाले परिणाम (लोकेल) में परिणाम दिखाने की आवश्यकता नहीं है। उदाहरण के लिए, यदि आपको केवल एक स्ट्रिंग द्वारा अनुक्रमित डेटा की बड़ी संख्या तक पहुंचने की आवश्यकता है, तो आप उस स्ट्रिंग द्वारा अनुक्रमित मानचित्र का उपयोग करेंगे। यह शायद पूरी तरह से strcoll() का उपयोग कर जो आम तौर पर बहुत धीमी गति से

वर्ण आप भी Unicode वेबसाइट की जाँच कर सकते हैं के बारे में जानकारी के लिए (strcmp() कम से कम। की तुलना में) है उन सॉर्ट करने के लिए बेकार है।

लोकेल के संबंध में, यह भाषा है। डिफ़ॉल्ट रूप से यह "सी" पर सेट होता है (अधिक या कम, कोई लोकेल नहीं)। एक बार जब आप कोई स्थान चुन लेते हैं तो लोकेल तदनुसार सेट किया जाता है। आप एलसी_LOCALE पर्यावरण परिवर्तक भी सेट कर सकते हैं। वास्तव में ऐसे कई चर हैं। लेकिन आम तौर पर आप पूर्व परिभाषित कार्यों का उपयोग करते हैं जो स्वचालित रूप से उन चरों को खाते में लेते हैं और आपके लिए सही काम करते हैं। (यानी प्रारूप दिनांक/समय, प्रारूप संख्या/उपायों, ऊपरी/निचले मामले की गणना आदि)

+1

+1 इस उत्तर में चरित्र तुलना के नमूने बहुत अच्छी तरह से प्रस्तुत किए गए हैं, खासकर "हालांकि, एफ से पहले है।" उदाहरण। इसी प्रकार, आंतरिक सॉर्ट प्रबंधन बनाम प्रदर्शन के लिए 'strcmp() 'का उपयोग करने के बारे में नोट्स समान रूप से अच्छी तरह से किए जाते हैं। ऐसे कुछ जवाब हैं जो संक्षेप में हैं और वॉल्यूम बोलते हैं, और मेरी इच्छा है कि मैं उन्हें एक से अधिक बार वोट दूंगा। यह उनमें से एक है। – WhozCraig

2

ग्लिब के कई अलग-अलग संस्करणों पर परीक्षण किए गए सभी यूनिकोड लोकेशंस में किसी कारण से, strcoll() किसी भी दो के लिए शून्य देता है hiraganas। यह सॉर्ट, uniq, और कुछ भी जो किसी भी तरह से स्ट्रिंग के ऑर्डर के साथ इंटरैक्ट करता है।

$ echo -e -n 'い \ n ろ \ n は \ n に \ n ほ \ n へ \ n と \ n' | सॉर्ट | uniq

जो केवल मरम्मत के परे टूट गया है। दुनिया के विभिन्न स्थानों के लोगों के पास अलग-अलग विचार हो सकते हैं कि 'い' को 'ろ' के पहले या बाद में रखा जाना चाहिए, लेकिन कोई भी उन्हें समझ नहीं पाएगा।

और कोई, जापानी एक करने के लिए अपने स्थान की स्थापना कोई फर्क नहीं पड़ता:

$ LC_ALL = ja_JP.utf8 LANG = ja_JP.utf8 LC_COLLATE = ja_jp।utf8 echo -e -n 'い \ n ろ \ n は \ n に \ n ほ \ n へ \ n と \ n' | सॉर्ट | uniq

कुछ सरकारी मेलिंग सूची में चर्चा हुई थी, लेकिन लगता है क्या, यह 2002 में था और यह तय नहीं किया गया है क्योंकि लोगों को परवाह नहीं है: https://www.mail-archive.com/[email protected]/msg02658.html

बग को क्या हुआ कि हमें कुछ दिनों में और अंत में कोलाइट लोकेल को "सी" में सेट करने और यूटीएफ -8 एन्कोडिंग के अच्छे गुणों पर भरोसा करने का हमारा एकमात्र तरीका था। यह एक भयानक अनुभव है, क्योंकि सभी जापानी डेटा को संसाधित करते समय वास्तव में "सी" लोकेल के तहत काम नहीं करना चाहिए।

तो अपनी स्वच्छता के लिए, सीधे स्ट्रोक का उपयोग न करें। का अधिक सुरक्षित संस्करण हो सकता है:

int safe_strcoll(const char *a, const char *b) 
{ 
    int ret = strcoll(a, b); 
    if (ret != 0) return ret; 
    return strcmp(a, b); 
} 

सिर्फ मामले strcoll में() आप पेंच का निर्णय लेता है ...

+1

मैं समस्या को हल करने के लिए भाग्यशाली था। आपका पर्यावरण परिवर्तन केवल 'echo' पर लागू होता है। आपको भाषा को 'सॉर्ट' और' uniq' 'में भी लागू करना चाहिए; सबसे आसान है 'LANG निर्यात करें'। यह पूरी तरह से काम करता है: '(निर्यात LANG = ja_JP.UTF-8; echo -e -n 'い \ n ろ \ n は \ n に \ n ほ \ n へ \ n と \ n' | sort | uniq)' । – qsantos

+1

इसे इंगित करने के लिए धन्यवाद। सिवाय इसके कि मैं वास्तव में इस प्रयोग को करते समय निर्यात LANG = ja_JP.UTF-8 का उपयोग कर रहा था। मैंने कई मशीनों पर दोबारा कोशिश की और अभी भी कुछ में समस्या का पुनरुत्पादन कर सकते हैं, लेकिन उनमें से सभी नहीं। मुझे लगता है कि मुझे थोड़ा और खोदने की जरूरत है क्योंकि अंतर क्या हुआ। glibc संस्करण एकमात्र चर नहीं है जिसे मुझे नियंत्रित करने की आवश्यकता है ... –

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