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

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

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

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

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

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

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

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

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

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

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

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

ऐतिहासिक दस्तावेज़ीकरण में सी स्ट्रिंग के लिए "बाइट" के स्थान पर प्रायः "लिपि" शब्द का उपयोग किया जाता था। जिससे कई लोगों को यह विश्वास हो जाता है कि ये फ़ंक्शन किसी प्रकार यूटीएफ-8 के लिए कार्य नहीं करते हैं। वास्तव में सभी लंबाई को बाइट्स के रूप में परिभाषित किया गया है और यह सभी कार्यान्वयनों में सच है ये फ़ंक्शन यूटीएफ -8 के साथ-साथ एकल बाइट एन्कोडिंग के साथ भी कार्य करते हैं। इसे स्पष्ट करने के लिए बीएसडी दस्तावेज़ को ठीक कर दिया गया है, लेकिन पॉज़िक्स, लिनक्स और विंडोज़ दस्तावेज़ अभी भी कई स्थानों पर  का उपयोग करते हैं। जहां "बाइट" या 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 में मुक्त-बीएसडी 2.4 में दिखाई दिए थे। ये फ़ंक्शन सदैव गंतव्य बफर में एक एनयूएल लिखते हैं, यदि आवश्यक हो तो परिणाम को छोटा कर देते हैं, और आवश्यक बफर के आकार को वापस कर देते हैं, जो ट्रंकेशन का पता लगाने की स्वीकृति देते है और एक नया बफर बनाने के लिए एक आकार प्रदान करते है जो ट्रंकेट नहीं होते है। कथित रूप से अप्रभावी सी स्ट्रिंग (स्ट्रिंग के कुछ वैकल्पिक रूप के अतिरिक्त) के उपयोग को प्रोत्साहित करने, और अन्य संभावित त्रुटियों को छिपाने के आधार पर उनकी आलोचना की गई है।  जिसके परिणाम स्वरूप उन्हें जीएनयू सी लाइब्रेरी (लिनक्स पर सॉफ्टवेयर द्वारा उपयोग किया जाता है) में सम्मिलित नहीं किया गया है। हालांकि उन्हें मुक्त-बीएसडी, फ्रीबीएसडी, नेटबीएसडी, सोलारिस, ओएस एक्स और क्यूएनएक्स के लिए सी लाइब्रेरी के साथ-साथ वैकल्पिक सी लाइब्रेरी में भी प्रयुक्त किया गया है। लिनक्स के लिए जैसे कि lएलआईबीबीएसडी को 2008 में प्रस्तुत किया गया था और एमयूएसएल को 2011 में प्रस्तुत किया गया था।  जीएनयू सी लाइब्रेरी समर्थन की कमी ने विभिन्न सॉफ्टवेयर लेखकों को इसका उपयोग करने और अन्य एसडीएल, जीएलआईबी, एफएफएमपीईजी, आरसिंक और यहां तक ​​​​कि आंतरिक रूप से लिनक्स कर्नेल में प्रतिस्थापन को एकत्र करने से नहीं रोका है। इन फंक्शन के लिए मुक्त-स्रोत कार्यान्वयन उपलब्ध हैं।

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

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

यह भी देखें

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

बाहरी संबंध

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