2011-08-08 19 views
6

जब मैं src_str से dst_arr और क्यों कॉपी करना चाहता हूं तो मुझे क्या उपयोग करना चाहिए?मेरे मामले में strncpy या strlcpy

char dst_arr[10]; 
char *src_str = "hello"; 

पुनश्च: मेरे सिर कैसे अच्छा या बुराstrncpy और strlcpy है पर बहुत कुछ पढ़ने के बाद तेजी से अपने कंप्यूटर की डिस्क से स्पिन हो रही है।

नोट: मुझे पता है strlcpy हर जगह उपलब्ध नहीं है। यह चिंता नहीं है।

उत्तर

20

strncpyकभी नहीं सही जवाब है जब अपने गंतव्य स्ट्रिंग शून्य समाप्त होता है के लिए अंक dst_ptr करने के लिए। strncpy एक ऐसा फ़ंक्शन है जिसका उपयोग गैर-समाप्त निश्चित-चौड़ाई तारों के साथ किया जाना है। अधिक सटीक, इसका उद्देश्य एक शून्य-समाप्त स्ट्रिंग को एक गैर-समाप्ति वाली निश्चित-चौड़ाई वाली स्ट्रिंग (प्रतिलिपि बनाकर) में परिवर्तित करना है। दूसरे शब्दों में, strncpy अर्थपूर्ण रूप से यहां लागू नहीं है।

आपके पास यहां मौजूद वास्तविक विकल्प strlcpy और सादा strcpy के बीच है।

आप dst_arr को "सुरक्षित" (अर्थात संभावित छोटा) नकल प्रदर्शन करने के लिए चाहते हैं, तो उपयोग करने के लिए उचित समारोह strlcpy है।

dst_ptr के लिए ... "dst_ptr पर प्रतिलिपि" जैसी कोई चीज़ नहीं है। आप मेमोरी पर dst_ptr पर प्रतिलिपि बना सकते हैं, लेकिन पहले आपको यह सुनिश्चित करना होगा कि यह कहीं कहीं इंगित करता है और उस स्मृति को आवंटित करता है। ऐसा करने के कई तरीके हैं।

उदाहरण के लिए, आप dst_ptr को dst_arr पर इंगित करने के लिए बना सकते हैं, इस मामले में उत्तर पिछले मामले के समान है - strlcpy

या आप malloc का उपयोग कर स्मृति आवंटित कर सकते हैं। यदि आपके द्वारा आवंटित स्मृति की मात्रा स्ट्रिंग के लिए पर्याप्त होने की गारंटी है (यानी कम से कम strlen(src_str) + 1 बाइट आवंटित किए गए हैं), तो आप स्ट्रिंग की प्रतिलिपि बनाने के लिए सादे strcpy या memcpy का उपयोग कर सकते हैं। इस मामले में strlcpy का उपयोग करने की कोई आवश्यकता नहीं है और कोई कारण नहीं है, हालांकि कुछ लोग इसका उपयोग करना पसंद कर सकते हैं, क्योंकि यह किसी भी तरह उन्हें अतिरिक्त सुरक्षा की भावना देता है।

यदि आप जानबूझकर कम स्मृति आवंटित करते हैं (यानी आप अपनी स्ट्रिंग को छोटा करना चाहते हैं), तो strlcpy उपयोग करने के लिए सही कार्य बन जाता है।

+1

धन्यवाद। जब आप कहते हैं कि "जब आप शून्य-समाप्त तारों के साथ काम कर रहे हों तो strncpy सही जवाब नहीं है", तो आपका मतलब स्रोत स्ट्रिंग या dest? – hari

+2

@hari: गंतव्य स्ट्रिंग। 'strncpy' एक * रूपांतरण * फ़ंक्शन है, जो शून्य-समाप्त स्रोत स्ट्रिंग को एक गैर-समाप्तिित निश्चित-चौड़ाई लक्ष्य स्ट्रिंग में परिवर्तित करता है। – AnT

+0

तो, यदि मेरी गंतव्य स्ट्रिंग 'char dst_arr [10] है, 'वह शून्य-समाप्त नहीं है। तो मुझे 'strlcpy' सही का उपयोग करना चाहिए? – hari

4

strlcpy() strncpy() से सुरक्षित है ताकि आप इसका भी उपयोग कर सकें।
जिन सिस्टमों में यह नहीं है, उनमें अक्सर एक s_strncpy() होगा जो वही काम करता है।

नोट आप कुछ भी कॉपी नहीं कर सकते जब तक यह कुछ

+1

यह थोड़ा सुरक्षित है, लेकिन सुरक्षित भी नहीं है। जैसे strlcpy गंतव्य स्ट्रिंग को गंतव्य में फिट करने के लिए छंटनी करता है, जो एक सुरक्षा जोखिम है। – rurban

2

मुझे strlcpy के बारे में पता नहीं था।() फ़ंक्शन कॉपी और क्रमशः तार श्रेणीबद्ध

strlcpy() और strlcat: मैं बस पाया here कि। वे सुरक्षित, अधिक संगत, और स्ट्रैन्स्पी (3) और strncat (3) के लिए कम त्रुटि प्रवण प्रतिस्थापन के लिए डिज़ाइन किए गए हैं।

तो strlcpy seams सुरक्षित।

संपादित करें: एक पूर्ण चर्चा here उपलब्ध है।

EDIT2:

मुझे लगता है कि मैं क्या लिखा है ऊपर अपने प्रश्न का "आपके मामले में" भाग उत्तर नहीं देता। यदि आप strncpy की सीमाओं को समझते हैं, तो मुझे लगता है कि आप इसका उपयोग कर सकते हैं और इसके नुकसान से बचने के लिए इसके आसपास अच्छा कोड लिख सकते हैं; लेकिन यदि आप इसकी सीमाओं की समझ के बारे में निश्चित नहीं हैं, तो strlcpy का उपयोग करें।

strncpy और strlcpy की सीमाओं की मेरी समझ यह है कि आप strncpy (बफर ओवरफ़्लो) के साथ कुछ बहुत बुरा कर सकते हैं, और सबसे खराब आप स्ट्रैस्पी के साथ कर सकते हैं प्रक्रिया में एक char को खोना है।

+0

स्पष्टीकरण के लिए धन्यवाद। मैं 'charlcpy' में एक char कैसे खो सकता हूं? क्या आप समझा सकते हैं? – hari

+0

यदि आप अपने बफर से बड़े स्ट्रिंग की प्रतिलिपि बनाने के लिए strncpy का उपयोग करते हैं, तो यह बफर के अंत में '' \ 0'' नहीं रखेगा। यदि आप strlcpy का उपयोग करते हैं, तो '' \ 0'' वहां होगा, लेकिन आपके बफर में एक कम चार होगा। तो अगर किसी ने strncpy का उपयोग किया है, तो उसे memcpy का उपयोग करना चाहिए था, strncpy के बजाय strlcpy का उपयोग करके उसे एक char खो देंगे। – jfg956

+0

धन्यवाद। तो जब 'strlcpy' का उपयोग करते समय केवल देखभाल करने की आवश्यकता होती है, तो आपको गंतव्य प्रदान करना चाहिए (शून्य के लिए src_length + 1)। सही बात? – hari

-1

सबसे पहले, आपके dst_ptr में आवंटित कोई स्थान नहीं है और आपने इसे दूसरों पर इंगित करने के लिए सेट नहीं किया है, इसलिए इससे कुछ भी असाइन करना संभवतः विभाजन खंड का कारण बन जाएगा।

strncpy पूरी तरह से काम करना चाहिए ठीक - बस कार्य करें:

strncpy(dst_arr, src_str, sizeof(dst_arr)); 

और आप जानते हैं कि आप अतिप्रवाह dst_arr अभ्यस्त। यदि आप एक बड़े src_str का उपयोग करते हैं तो आपको dst_arr के अंत में अपना स्वयं का शून्य टर्मिनेटर रखना पड़ सकता है, लेकिन इस मामले में आपका स्रोत < आपका भाग है, इसलिए इसे किसी भी तरह से नल के साथ गद्देदार किया जाएगा।

यह हर जगह काम करता है और इसकी सुरक्षित है, इसलिए जब तक इसकी बौद्धिक जिज्ञासा नहीं होती तब तक मैं कुछ और नहीं देखता।

भी ध्यान रखें कि यह 10 के लिए एक गैर-जादुई संख्या उपयोग करें ताकि आप इस बात का आकार strncpy :)

+0

'strncpy' लगभग सही चीज़ नहीं है, क्योंकि यह शून्य-भरता है लेकिन शून्य-समाप्त नहीं होता है। ओपी 'strlcpy' चाहता है, जो शून्य-टर्मिनेट करता है और शून्य-भर नहीं देता है। साथ ही, "इस मामले में" के बारे में बात करने की गलती है, क्योंकि पाठ्यक्रम का सवाल सिर्फ एक उदाहरण है ... असली कोड एक निश्चित स्ट्रिंग को कॉपी करने वाला नहीं है जैसे कि "हैलो" एक निश्चित आकार के बफर को बड़ा माना जाता है ।ओपी की जरूरतों के लिए –

-1

आप strncpy उपयोग नहीं करना चाहिए और न इस के लिए strlcpy के आकार से मेल खाता है पता अच्छा होगा । बेहतर आप

*dst_arr=0; strncat(dst_arr,src_arr,(sizeof dst_arr)-1); 

या

sprintf(dst_arr,"%.*s",(sizeof dst_arr)-1,src_arr); 

dst_arr यहाँ का उपयोग एक आरंभीकरण के बिना एक सरणी नहीं एक सूचक होना चाहिए।

+2

'strlcpy' का उपयोग किया जा सकता है। –

1

आपको हमेशा मानक फ़ंक्शन होना चाहिए, जो इस मामले में C11 strcpy_s() फ़ंक्शन है। strncpy() नहीं, क्योंकि यह असुरक्षित शून्य समाप्ति की गारंटी नहीं दे रहा है। और ओपनबीएसडी-केवल strlcpy() नहीं, क्योंकि यह भी असुरक्षित है, और ओपनबीएसडी हमेशा अपने स्वयं के आविष्कारों के साथ आता है, जो आम तौर पर इसे किसी भी मानक में नहीं बनाते हैं।

देखें http://en.cppreference.com/w/c/string/byte/strcpy

समारोह strcpy_s कि strlcpy को छोड़कर, बीएसडी समारोह strlcpy के समान है ट्रंकेटस स्रोत स्ट्रिंग गंतव्य में फिट करने के लिए (जो एक सुरक्षा जोखिम है)

  • strlcpy करता है सभी रनटाइम चेक निष्पादित न करें जो strcpy_s करता है
  • strlcpy गंतव्य को शून्य स्ट्रिंग पर सेट करके या कॉल विफल होने पर हैंडलर को कॉल करके विफलताओं को स्पष्ट नहीं करता है।
  • हालांकि संभावित सुरक्षा जोखिमों के कारण strcpy_s छंटनी को प्रतिबंधित करता है, इसके बजाय बाउंड-चेक किए गए strncpy_s का उपयोग करके एक स्ट्रिंग को छोटा करना संभव है।

यदि आपकी सी लाइब्रेरी में strcpy_s नहीं है, तो सुरक्षित lib का उपयोग करें। https://rurban.github.io/safeclib/doc/safec-3.1/df/d8e/strcpy__s_8c.html