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

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

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

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

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

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

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

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

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

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

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

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

फंक्शन
{| class="wikitable" ! ! बाइट स्ट्रिंग ! वाइड स्ट्रिंग ! विवरण ! rowspan=5 | स्ट्रिंग प्रकलन (कंप्यूटर) ! rowspan=11 | स्ट्रिंग परीक्षण !विविध ! rowspan=5 | मेमोरी प्रकलन (कंप्यूटर)
 * strcpy
 * wcscpy
 * एक स्ट्रिंग को दूसरे में कॉपी करता है।
 * strncpy
 * wcsncpy
 * स्रोत से कॉपी करके या शून्य जोड़कर बिल्कुल n बाइट्स लिखता है।
 * strcat
 * wcscat
 * एक स्ट्रिंग को दूसरे से जोड़ता है।
 * strncat
 * wcsncat
 * एक स्ट्रिंग से दूसरे स्ट्रिंग में n बाइट्स से अधिक नहीं जोड़ता
 * strxfrm
 * wcsxfrm
 * वर्तमान स्थान के अनुसार एक स्ट्रिंग को रूपांतरित करता है।
 * strxfrm
 * wcsxfrm
 * वर्तमान स्थान के अनुसार एक स्ट्रिंग को रूपांतरित करता है।
 * वर्तमान स्थान के अनुसार एक स्ट्रिंग को रूपांतरित करता है।
 * strlen
 * wcslen
 * स्ट्रिंग की लंबाई लौटाता है।
 * strcmp
 * wcscmp
 * दो तारों की तुलना करता है। (तीन-तरफा तुलना)
 * strncmp
 * wcsncmp
 * दो स्ट्रिंग्स में बाइट्स की एक विशिष्ट संख्या की तुलना करता है।
 * strcoll
 * wcscoll
 * वर्तमान स्थान के अनुसार दो स्ट्रिंग की तुलना करता है।
 * strchr
 * wcschr
 * एक स्ट्रिंग में बाइट की पहली घटना ढूँढता है।
 * strrchr
 * wcsrchr
 * एक स्ट्रिंग में बाइट की अंतिम घटना ढूँढता है।
 * strspn
 * wcsspn
 * एक स्ट्रिंग में प्रारंभिक बाइट्स की संख्या लौटाता है। जो दूसरी स्ट्रिंग में हैं।
 * strcspn
 * wcscspn
 * एक स्ट्रिंग में प्रारंभिक बाइट्स की संख्या लौटाता है। जो दूसरी स्ट्रिंग में नहीं हैं।
 * strpbrk
 * wcspbrk
 * एक स्ट्रिंग में एक सेट में बाइट की पहली घटना ढूँढता है।
 * strstr
 * wcsstr
 * एक स्ट्रिंग में एक सबस्ट्रिंग की पहली घटना ढूँढता है।
 * strtok
 * wcstok
 * एक स्ट्रिंग को टोकन में विभाजित करता है।
 * wcspbrk
 * एक स्ट्रिंग में एक सेट में बाइट की पहली घटना ढूँढता है।
 * strstr
 * wcsstr
 * एक स्ट्रिंग में एक सबस्ट्रिंग की पहली घटना ढूँढता है।
 * strtok
 * wcstok
 * एक स्ट्रिंग को टोकन में विभाजित करता है।
 * wcstok
 * एक स्ट्रिंग को टोकन में विभाजित करता है।
 * strerror
 * N/A
 * त्रुटि कोड से प्राप्त संदेश वाली एक स्ट्रिंग लौटाता है।
 * memset
 * wmemset
 * एक बफ़र को बार-बार बाइट से भरता है।
 * memcpy
 * wmemcpy
 * एक बफ़र को दूसरे बफ़र में कॉपी करता है।
 * memmove
 * wmemmove
 * एक बफ़र को दूसरे संभवतः ओवरलैपिंग बफ़र में कॉपी करता है।
 * memcmp
 * wmemcmp
 * दो बफ़र्स की तीन-तरफ़ा तुलना करता है।
 * memchr
 * wmemchr
 * बफ़र में बाइट की पहली घटना ढूँढता है।
 * colspan=4 | और उन कार्यों के साथ जो बफर ओवरफ्लो की अनुमति नहीं देते हैं कोई स्वीकृत मानक उत्पन्न नहीं हुआ है। यह आंशिक रूप से कई सी प्रोग्रामरों द्वारा गलत धारणा के कारण है। कि   और   वांछित व्यवहार है। ; हालाँकि, इसके लिए कोई भी फ़ंक्शन डिज़ाइन नहीं किया गया था (उनका उद्देश्य अशक्त-गद्दीदार निश्चित-आकार के स्ट्रिंग बफ़र्स में हेरफेर करना था, आधुनिक सॉफ़्टवेयर में आमतौर पर कम उपयोग किया जाने वाला एक डेटा प्रारूप), और व्यवहार और तर्क गैर-सहज हैं। और अक्सर विशेषज्ञ द्वारा भी गलत तरीके से लिखे गए हैं।। प्रोग्रामर।
 * memchr
 * wmemchr
 * बफ़र में बाइट की पहली घटना ढूँढता है।
 * 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