सी स्ट्रिंग हैंडलिंग

C (प्रोग्रामिंग लैंग्वेज) प्रोग्रामिंग लैंग्वेज में अपने C मानक पुस्तकालय में स्ट्रिंग (कंप्यूटर विज्ञान)  (कैरेक्टर स्ट्रिंग्स और बाइट स्ट्रिंग्स) पर संचालन को लागू करने वाले कार्यों का एक सेट है। नकल, संघटन, टोकननाइजेशन (शाब्दिक विश्लेषण) और खोज जैसे विभिन्न संचालन समर्थित हैं। कैरेक्टर स्ट्रिंग्स के लिए, मानक लाइब्रेरी कन्वेंशन का उपयोग करती है कि स्ट्रिंग्स  अशक्त-समाप्त स्ट्रिंग  हैं | नल-टर्मिनेटेड: एक स्ट्रिंग $n$ वर्णों को एक सरणी (डेटा संरचना) के रूप में दर्शाया गया है $n + 1$ तत्व, जिनमें से अंतिम एक है NUL वर्ण (संख्यात्मक मान 0 के साथ)।

उचित प्रोग्रामिंग भाषा में स्ट्रिंग्स के लिए एकमात्र समर्थन यह है कि संकलक उद्धृत स्ट्रिंग शाब्दिकों को अशक्त-समाप्त स्ट्रिंग्स में अनुवादित करता है।

परिभाषाएँ
एक स्ट्रिंग को पहली शून्य कोड इकाई (जिसे अक्सर एनयूएल कोड इकाई कहा जाता है) द्वारा समाप्त कोड इकाइयों के एक निरंतर अनुक्रम के रूप में परिभाषित किया जाता है। इसका मतलब है कि एक स्ट्रिंग में शून्य कोड इकाई नहीं हो सकती है, क्योंकि पहली बार देखा गया स्ट्रिंग के अंत को चिह्नित करता है। एक स्ट्रिंग की लंबाई शून्य कोड इकाई से पहले कोड इकाइयों की संख्या है। एक स्ट्रिंग द्वारा कब्जा की गई मेमोरी हमेशा लंबाई की तुलना में एक अधिक कोड इकाई होती है, क्योंकि शून्य टर्मिनेटर को स्टोर करने के लिए जगह की आवश्यकता होती है।

आम तौर पर, स्ट्रिंग शब्द का अर्थ एक स्ट्रिंग होता है जहां कोड इकाई प्रकार की होती है, जो सभी आधुनिक मशीनों पर ठीक 8 बिट्स है। C90 (सी संस्करण) व्यापक स्ट्रिंग्स को परिभाषित करता है जो प्रकार की एक कोड इकाई का उपयोग करते हैं  , जो आधुनिक मशीनों पर 16 या 32 बिट है। यह यूनिकोड के लिए अभिप्रेत था लेकिन इसके बजाय यूनिकोड के लिए सामान्य स्ट्रिंग्स में UTF-8 का उपयोग करना आम बात है।

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

स्ट्रिंग शाब्दिक ( सी स्रोत कोड में) संकलन के दौरान सरणियों में परिवर्तित हो जाते हैं। परिणाम कोड इकाइयों की एक सरणी है जिसमें सभी वर्ण और एक अनुगामी शून्य कोड इकाई होती है। C90 में   एक विस्तृत तार उत्पन्न करता है। एक स्ट्रिंग शाब्दिक में शून्य कोड इकाई हो सकती है (एक तरीका है   स्रोत में), लेकिन इससे उस बिंदु पर स्ट्रिंग समाप्त हो जाएगी। शेष शाब्दिक स्मृति में रखा जाएगा (अंत में एक और शून्य कोड इकाई के साथ जोड़ा जाएगा) लेकिन यह जानना असंभव है कि उन कोड इकाइयों को स्ट्रिंग शाब्दिक से अनुवादित किया गया था, इसलिए ऐसा स्रोत कोड एक स्ट्रिंग शाब्दिक नहीं है।

कैरेक्टर एनकोडिंग
प्रत्येक स्ट्रिंग उपयुक्त प्रकार की शून्य कोड इकाई की पहली घटना पर समाप्त होती है ( या  ). नतीजतन, एक बाइट स्ट्रिंग (char*) में ASCII या किसी विस्तारित ASCII में गैर-शून्य वर्ण वर्ण हो सकते हैं, लेकिन UTF-16 जैसे एन्कोडिंग में वर्ण नहीं (भले ही एक 16-बिट कोड इकाई अशून्य हो, इसकी उच्च या निम्न बाइट शून्य हो सकती है)। वाइड स्ट्रिंग्स में स्टोर किए जा सकने वाले एनकोडिंग को विड्थ द्वारा परिभाषित किया जाता है. अधिकांश कार्यान्वयन में,  कम से कम 16 बिट है, और इसलिए सभी 16-बिट एनकोडिंग, जैसे कि UCS-2, को संग्रहीत किया जा सकता है। अगर   32-बिट है, तो 32-बिट एनकोडिंग, जैसे कि UTF-32, संग्रहीत किया जा सकता है। (मानक के लिए एक प्रकार की आवश्यकता होती है जो किसी भी विस्तृत वर्ण को धारण करता है, जो विंडोज़ पर अब UCS-2 से UTF-16 शिफ्ट के बाद से सही नहीं है। इसे मानक में एक दोष के रूप में पहचाना गया और C++ में तय किया गया।) C++11 और C11 स्पष्ट चौड़ाई के साथ दो प्रकार जोड़ते हैं char16_t और char32_t. चर-चौड़ाई एनकोडिंग का उपयोग बाइट स्ट्रिंग्स और वाइड स्ट्रिंग्स दोनों में किया जा सकता है। स्ट्रिंग की लंबाई और ऑफ़सेट को बाइट्स या में मापा जाता है, पात्रों में नहीं, जो शुरुआती प्रोग्रामरों को भ्रमित कर सकता है। UTF-8 और Shift JIS का उपयोग अक्सर C बाइट स्ट्रिंग्स में किया जाता है, जबकि UTF-16 का उपयोग अक्सर C वाइड स्ट्रिंग्स में किया जाता है जब   16 बिट है। जैसे कार्यों का उपयोग करके चर-चौड़ाई वाले वर्णों को छोटा करना   स्ट्रिंग के अंत में अमान्य अनुक्रम उत्पन्न कर सकता है। यह असुरक्षित हो सकता है यदि काटे गए हिस्सों को कोड द्वारा व्याख्या किया जाता है जो मानता है कि इनपुट मान्य है।

यूनिकोड शाब्दिक के लिए समर्थन जैसे char foo[512] = "φωωβαρ"; (यूटीएफ-8) या wchar_t foo[512] = L"φωωβαρ"; (UTF-16 या UTF-32, पर निर्भर करता है wchar_t) कार्यान्वयन परिभाषित है, और आवश्यकता हो सकती है कि स्रोत कोड एक ही एन्कोडिंग में हो, विशेष रूप से के लिए char जहां संकलक उद्धरणों के बीच जो कुछ भी है उसे कॉपी कर सकते हैं। कुछ संकलक या संपादकों को सभी गैर-ASCII वर्णों को दर्ज करने की आवश्यकता होगी  UTF-8 के प्रत्येक बाइट के लिए अनुक्रम, और/या   UTF-16 के प्रत्येक शब्द के लिए। सी 11 (और सी ++ 11) के बाद से, एक नया char foo[512] = u8"φωωβαρ"; लिटरल सिंटैक्स उपलब्ध है जो बाइटस्ट्रिंग लिटरल के लिए UTF-8 की गारंटी देता है। C++20 और C23 (C मानक संशोधन) के बाद से, a   प्रकार जोड़ा गया था जो यूटीएफ -8 अक्षरों को स्टोर करने के लिए है और यू 8 प्रीफिक्स्ड कैरेक्टर और स्ट्रिंग अक्षर के प्रकार बदल दिए गए थे   और   क्रमश।

कार्यों का अवलोकन
सी स्ट्रिंग्स पर चलने वाले अधिकांश कार्यों को घोषित किया जाता है  हेडर (  सी ++ में), जबकि सी वाइड स्ट्रिंग्स पर काम करने वाले कार्यों को घोषित किया जाता है   हेडर (  सी ++ में)। इन शीर्षकों में मेमोरी बफ़र्स को संभालने के लिए उपयोग किए जाने वाले कार्यों की घोषणाएँ भी होती हैं; नाम इस प्रकार एक मिथ्या नाम है।

में घोषित कार्य  सी मानक पुस्तकालय के एक हिस्से के रूप में बेहद लोकप्रिय हैं, उन्हें सी का समर्थन करने वाले किसी भी मंच पर काम करने की गारंटी है। हालांकि, इन कार्यों के साथ कुछ सुरक्षा समस्याएं मौजूद हैं, जैसे संभावित  बफ़र अधिकता  जब सावधानी से और ठीक से उपयोग नहीं किया जाता है, जिससे प्रोग्रामर सुरक्षित और संभवतः कम पोर्टेबल वेरिएंट पसंद करते हैं, जिनमें से कुछ लोकप्रिय नीचे सूचीबद्ध हैं। इनमें से कुछ फ़ंक्शन a को स्वीकार करके कॉन्स्ट-शुद्धता का भी उल्लंघन करते हैं   स्ट्रिंग सूचक और एक गैर-वापसी  स्ट्रिंग के भीतर सूचक। इसे ठीक करने के लिए, कुछ को मानक लाइब्रेरी के C++ संस्करण में दो फंक्शन ओवरलोडिंग में विभाजित किया गया है।

ऐतिहासिक प्रलेखन में सी स्ट्रिंग्स के लिए बाइट के बजाय शब्द वर्ण का उपयोग अक्सर किया जाता था, जो कई का नेतृत्व करता है यह मानने के लिए कि ये कार्य किसी तरह UTF-8 के लिए काम नहीं करते हैं। वास्तव में सभी लंबाई को बाइट्स के रूप में परिभाषित किया गया है और यह सभी कार्यान्वयनों में सच है, और ये कार्य UTF-8 के साथ-साथ सिंगल-बाइट एन्कोडिंग के साथ भी काम करते हैं। इसे स्पष्ट करने के लिए बीएसडी प्रलेखन तय किया गया है, लेकिन POSIX, Linux, और Windows प्रलेखन अभी भी कई स्थानों पर वर्ण का उपयोग करता है जहां बाइट या wchar_t सही शब्द है।

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

कार्य
{| class="wikitable" ! ! Byte string ! Wide string ! Description ! rowspan=5 | String manipulation ! rowspan=11 | String examination ! Miscellaneous ! rowspan=5 | Memory manipulation
 * strcpy
 * wcscpy
 * Copies one string to another
 * strncpy
 * wcsncpy
 * Writes exactly $n$ bytes, copying from source or adding nulls
 * strcat
 * wcscat
 * Appends one string to another
 * strncat
 * wcsncat
 * Appends no more than $n$ bytes from one string to another
 * strxfrm
 * wcsxfrm
 * Transforms a string according to the current locale
 * strxfrm
 * wcsxfrm
 * Transforms a string according to the current locale
 * Transforms a string according to the current locale
 * strlen
 * wcslen
 * Returns the length of the string
 * strcmp
 * wcscmp
 * Compares two strings (three-way comparison)
 * strncmp
 * wcsncmp
 * Compares a specific number of bytes in two strings
 * strcoll
 * wcscoll
 * Compares two strings according to the current locale
 * strchr
 * wcschr
 * Finds the first occurrence of a byte in a string
 * strrchr
 * wcsrchr
 * Finds the last occurrence of a byte in a string
 * strspn
 * wcsspn
 * Returns the number of initial bytes in a string that are in a second string
 * strcspn
 * wcscspn
 * Returns the number of initial bytes in a string that are not in a second string
 * strpbrk
 * wcspbrk
 * Finds in a string the first occurrence of a byte in a set
 * strstr
 * wcsstr
 * Finds the first occurrence of a substring in a string
 * strtok
 * wcstok
 * Splits a string into tokens
 * wcspbrk
 * Finds in a string the first occurrence of a byte in a set
 * strstr
 * wcsstr
 * Finds the first occurrence of a substring in a string
 * strtok
 * wcstok
 * Splits a string into tokens
 * wcstok
 * Splits a string into tokens
 * strerror
 * N/A
 * Returns a string containing a message derived from an error code
 * memset
 * wmemset
 * Fills a buffer with a repeated byte
 * memcpy
 * wmemcpy
 * Copies one buffer to another
 * memmove
 * wmemmove
 * Copies one buffer to another, possibly overlapping, buffer
 * memcmp
 * wmemcmp
 * Compares two buffers (three-way comparison)
 * memchr
 * wmemchr
 * Finds the first occurrence of a byte in a buffer
 * colspan=4 | और उन कार्यों के साथ जो बफर ओवरफ्लो की अनुमति नहीं देते हैं, कोई स्वीकृत मानक उत्पन्न नहीं हुआ है। यह आंशिक रूप से कई सी प्रोग्रामरों द्वारा गलत धारणा के कारण है कि   और   वांछित व्यवहार है; हालाँकि, इसके लिए कोई भी फ़ंक्शन डिज़ाइन नहीं किया गया था (उनका उद्देश्य अशक्त-गद्दीदार निश्चित-आकार के स्ट्रिंग बफ़र्स में हेरफेर करना था, आधुनिक सॉफ़्टवेयर में आमतौर पर कम उपयोग किया जाने वाला एक डेटा प्रारूप), और व्यवहार और तर्क गैर-सहज हैं और अक्सर विशेषज्ञ द्वारा भी गलत तरीके से लिखे गए हैं। प्रोग्रामर।
 * memchr
 * wmemchr
 * Finds the first occurrence of a byte in a buffer
 * colspan=4 | और उन कार्यों के साथ जो बफर ओवरफ्लो की अनुमति नहीं देते हैं, कोई स्वीकृत मानक उत्पन्न नहीं हुआ है। यह आंशिक रूप से कई सी प्रोग्रामरों द्वारा गलत धारणा के कारण है कि   और   वांछित व्यवहार है; हालाँकि, इसके लिए कोई भी फ़ंक्शन डिज़ाइन नहीं किया गया था (उनका उद्देश्य अशक्त-गद्दीदार निश्चित-आकार के स्ट्रिंग बफ़र्स में हेरफेर करना था, आधुनिक सॉफ़्टवेयर में आमतौर पर कम उपयोग किया जाने वाला एक डेटा प्रारूप), और व्यवहार और तर्क गैर-सहज हैं और अक्सर विशेषज्ञ द्वारा भी गलत तरीके से लिखे गए हैं। प्रोग्रामर।
 * colspan=4 | और उन कार्यों के साथ जो बफर ओवरफ्लो की अनुमति नहीं देते हैं, कोई स्वीकृत मानक उत्पन्न नहीं हुआ है। यह आंशिक रूप से कई सी प्रोग्रामरों द्वारा गलत धारणा के कारण है कि   और   वांछित व्यवहार है; हालाँकि, इसके लिए कोई भी फ़ंक्शन डिज़ाइन नहीं किया गया था (उनका उद्देश्य अशक्त-गद्दीदार निश्चित-आकार के स्ट्रिंग बफ़र्स में हेरफेर करना था, आधुनिक सॉफ़्टवेयर में आमतौर पर कम उपयोग किया जाने वाला एक डेटा प्रारूप), और व्यवहार और तर्क गैर-सहज हैं और अक्सर विशेषज्ञ द्वारा भी गलत तरीके से लिखे गए हैं। प्रोग्रामर।

सबसे लोकप्रिय प्रतिस्थापन हैं  और   कार्य, जो दिसंबर, 1998 में OpenBSD 2.4 में दिखाई दिए। ये फ़ंक्शन हमेशा गंतव्य बफर में एक एनयूएल लिखते हैं, यदि आवश्यक हो तो परिणाम को छोटा कर देते हैं, और आवश्यक बफर के आकार को वापस कर देते हैं, जो ट्रंकेशन का पता लगाने की अनुमति देता है और एक नया बफर बनाने के लिए एक आकार प्रदान करता है जो छोटा नहीं होगा। कथित रूप से अक्षम होने के आधार पर उनकी आलोचना की गई है, सी स्ट्रिंग्स (स्ट्रिंग के कुछ बेहतर वैकल्पिक रूप के बजाय) के उपयोग को प्रोत्साहित करना, और अन्य संभावित त्रुटियों को छिपाना।  नतीजतन, उन्हें जीएनयू सी लाइब्रेरी (लिनक्स पर सॉफ़्टवेयर द्वारा उपयोग किया जाता है) में शामिल नहीं किया गया है, हालांकि वे ओपनबीएसडी, फ्रीबीएसडी, नेटबीएसडी, सोलारिस (ऑपरेटिंग सिस्टम), ओएस एक्स और क्यूएनएक्स के साथ-साथ सी पुस्तकालयों में भी लागू किए गए हैं। लिनक्स के लिए वैकल्पिक सी पुस्तकालयों में, जैसे libbsd, 2008 में पेश किया गया, और माँसपेशियाँ, 2011 में पेश किया गया।  GNU C लाइब्रेरी समर्थन की कमी ने विभिन्न सॉफ़्टवेयर लेखकों को इसका उपयोग करने और अन्य Simple_DirectMedia_Layer, GLib, FFmpeg, rsync, और यहाँ तक कि Linux कर्नेल में आंतरिक रूप से एक प्रतिस्थापन को बंडल करने से नहीं रोका है। इन कार्यों के लिए ओपन सोर्स कार्यान्वयन उपलब्ध हैं। कभी-कभी या  उपयोग किया जाता है, क्योंकि वे इससे अधिक कुशल हो सकते हैं   क्योंकि वे बार-बार एनयूएल की जांच नहीं करते हैं (यह आधुनिक प्रोसेसर पर कम सच है)। चूंकि उन्हें एक पैरामीटर के रूप में बफर लंबाई की आवश्यकता होती है, इस पैरामीटर की सही सेटिंग बफर ओवरफ्लो से बच सकती है।

अपने 2004 Microsoft सुरक्षा विकास जीवनचक्र के हिस्से के रूप में, Microsoft ने सुरक्षित कार्यों के एक परिवार की शुरुआत की, जिसमें शामिल हैं  और   (कई अन्य लोगों के साथ)। ISO/IEC WDTR 24731 द्वारा प्रस्तावित वैकल्पिक C11 (C मानक संशोधन)|C11 (अनुलग्नक K) के भाग के रूप में इन कार्यों को कुछ मामूली परिवर्तनों के साथ मानकीकृत किया गया था। ये कार्य विभिन्न जाँचों को निष्पादित करते हैं, जिसमें यह भी शामिल है कि स्ट्रिंग बफर में फ़िट होने के लिए बहुत लंबी है या नहीं।. यदि जांच विफल हो जाती है, तो उपयोगकर्ता द्वारा निर्दिष्ट रनटाइम-बाधा हैंडलर फ़ंक्शन को कॉल किया जाता है, जो आमतौर पर प्रोग्राम को बंद कर देता है। रनटाइम-बाधा हैंडलर को कॉल करने से पहले कुछ फ़ंक्शन विनाशकारी संचालन करते हैं; उदाहरण के लिए,   गंतव्य को खाली स्ट्रिंग पर सेट करता है, जो त्रुटि स्थितियों से पुनर्प्राप्त करना या उन्हें डीबग करना कठिन बना सकता है। इन कार्यों ने काफी आलोचना को आकर्षित किया क्योंकि शुरू में उन्हें केवल विंडोज पर लागू किया गया था और उसी समय माइक्रोसॉफ्ट विजुअल सी ++ ++ द्वारा चेतावनी संदेश उत्पन्न करना शुरू कर दिया गया था, जो प्रोग्रामर को मानक कार्यों के बजाय इन कार्यों का उपयोग करने का सुझाव दे रहे थे। कुछ लोगों द्वारा यह अनुमान लगाया गया है कि माइक्रोसॉफ्ट द्वारा डेवलपर्स को अपने प्लेटफॉर्म में लॉक करने का प्रयास किया जा रहा है। हालांकि इन कार्यों के ओपन-सोर्स कार्यान्वयन उपलब्ध हैं, ये कार्य सामान्य यूनिक्स सी पुस्तकालयों में मौजूद नहीं हैं। इन कार्यों के अनुभव ने उनके अपनाने और उपयोग में त्रुटियों के साथ महत्वपूर्ण समस्याएं दिखाई हैं, इसलिए सी मानक के अगले संशोधन के लिए अनुलग्नक के को हटाने का प्रस्ताव है। का उपयोग memset_s को अवांछित संकलक अनुकूलन से बचने के तरीके के रूप में भी सुझाया गया है।

यह भी देखें

 * – बैकस्लैश एस्केप सीक्वेंस सहित स्रोत कोड सिंटैक्स
 * स्ट्रिंग कार्य करता है
 * पर्ल संगत नियमित अभिव्यक्तियाँ (पीसीआरई)

बाहरी संबंध

 * Fast memcpy in C, multiple C coding examples to target different types of CPU instruction architectures