आपको स्ट्रॉन्की की जगह स्ट्रेंथ का इस्तेमाल क्यों करना चाहिए?


84

संपादित करें: मैंने उदाहरण के लिए स्रोत जोड़ा है।

मैं इस उदाहरण में आया :

जिसने इस उत्पादन का उत्पादन किया:

गंतव्य मूल रूप से = 'abcdefg' है
Strcpy के बाद, गंतव्य '123456789' बन जाता है

डेस्ट १ मूल रूप से है = 'एब्सडेफ'
अकड़ के बाद, गंतव्य 1 '12345fg' बन जाता है

जो मुझे आश्चर्यचकित करता है कि कोई भी इस प्रभाव को क्यों चाहेगा। ऐसा लग रहा है कि यह भ्रामक होगा। यह कार्यक्रम मुझे लगता है कि आप मूल रूप से टॉम ब्रोरो 3 के साथ किसी के नाम (जैसे टॉम ब्रोकॉ) की नकल कर सकते हैं।

strncpy() ओवर का उपयोग करने के क्या फायदे हैंstrcpy() ?


81
मुझे लगता है कि आपको यह पूछने का मतलब है कि "पृथ्वी पर कोई strcpyइसके बजाय क्यों इस्तेमाल करेगा strncpy?"
सैम हैरवेल

5
जब मैं सी में एक प्रथम सेमेस्टर प्रोग्रामिंग कोर्स के लिए टीए था, तो मैंने अपने छात्रों को आश्वासन दिया कि किसी भी तरीके का उपयोग getlineगलत परिणाम देगा जब मैंने सावधानी से तैयार किए गए इनपुट के खिलाफ उन्हें ग्रेड किया। :)
सैम हरवेल

4
मुझे लगता है कि आपने गलत समझा है कि वास्तव में कोड क्या करता है। करीब से देखो।
एमिल एच

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

7
यह बहुत अफ़सोस की बात नहीं है। मेरा मतलब है, इसने मुझे पूरी तरह से तोड़ दिया और उच्च स्तर की भाषाओं को और अधिक मज़ेदार बना दिया :)
कार्सन मायर्स

जवाबों:


98

strncpyकॉम्बैट बफर की अतिप्रवाह आपको इसमें एक लंबाई डालने की आवश्यकता होती है। strcpyअनुगामी पर निर्भर करता है \0, जो हमेशा नहीं हो सकता है।

दूसरे, आपने 7 वर्ण स्ट्रिंग पर केवल 5 वर्णों की प्रतिलिपि बनाने का विकल्प क्यों चुना, यह मेरे से परे है, लेकिन यह अपेक्षित व्यवहार पैदा कर रहा है। यह केवल पहले nपात्रों की नकल कर रहा है , जहां nतीसरा तर्क है।

सभी nकार्य बफर ओवरफ्लो के खिलाफ रक्षात्मक कोडिंग के रूप में उपयोग किए जाते हैं। कृपया उन्हें पुराने कार्यों के बदले में उपयोग करें, जैसे कि strcpy


47
देखें lysator.liu.se/c/rat/d11.html : strncpyशुरू में सी लाइब्रेरी में शुरू किया गया था ताकि डायरेक्टरी एंट्रीज जैसे स्ट्रक्चर्स में तय लंबाई के नाम फील्ड से निपटा जा सके। इस तरह के फ़ील्ड का उपयोग स्ट्रिंग्स के समान नहीं किया जाता है: अनुगामी नल अधिकतम लंबाई वाले क्षेत्र के लिए अनावश्यक है, और छोटे नामों के लिए अनुगामी बाइट्स सेट करने से कुशल फ़ील्ड-वार तुलनाओं का आश्वासन मिलता है। strncpyमूल रूप से "बंधे हुए स्ट्रैची" की उत्पत्ति नहीं है, और समिति ने इस तरह के उपयोग के लिए फ़ंक्शन को बेहतर ढंग से बदलने के बजाय मौजूदा अभ्यास को पहचानना पसंद किया है।
सिनान Augnür

35
मुझे यकीन नहीं है कि यह बहुत सारे वोट क्यों प्राप्त कर रहा है - strncpy को कभी भी strcpy के लिए एक सुरक्षित विकल्प के रूप में इरादा नहीं किया गया था और वास्तव में कोई भी सुरक्षित नहीं है क्योंकि यह स्ट्रिंग को समाप्त नहीं करता है। इसकी अलग कार्यक्षमता भी है कि यह NUL चर के साथ आपूर्ति की गई लंबाई को बढ़ाता है। जैसा कि कैफे अपने जवाब में कहता है - यह एक निश्चित आकार के सरणी में ओवरराइटिंग के लिए है।
डिपस्टिक

26
तथ्य यह है कि रहता है strncpy है नहीं की सुरक्षित संस्करण strcpy
सिनान Augnür

7
@ सीन: मैंने कभी नहीं कहा कि यह सुरक्षित था। यह रक्षात्मक है। यह आपको एक लंबाई में रखने के लिए मजबूर करता है, जिससे आप यह सोचते हैं कि आप क्या कर रहे हैं। बेहतर समाधान हैं, लेकिन तथ्य यह है कि लोग (और) का उपयोग करेंगेstrncpy इसके बजायstrcpy क्योंकि यह बहुत अधिक रक्षात्मक कार्य है ... जो कि उन्होंने कहा है।
एरिक

10
एन फ़ंक्शन सभी को बफर ओवरफ्लो के खिलाफ रक्षात्मक कोडिंग के रूप में उपयोग किया जाता है। कृपया उन्हें पुराने कार्यों के बदले में उपयोग करें, जैसे कि स्ट्रैची। यह सच है snprintf, लेकिन इसके लिए अप्रासंगिक strncatऔर पूरी तरह से असत्य है strncpy। इस उत्तर को इतने उत्थान कैसे मिले? यह दिखाता है कि इस संगीन कार्य को लेकर स्थिति कितनी खराब है। इसका उपयोग करना रक्षात्मक नहीं है: ज्यादातर स्थितियों में प्रोग्रामर इसके शब्दार्थ को नहीं समझता है और संभावित रूप से गैर शून्य समाप्त स्ट्रिंग बनाता है।
चकरली

180

strncpy()मूल यूनिक्स निर्देशिका प्रविष्टियों का ढंग से संग्रहीत जोड़ तोड़ तार: समारोह मन में एक बहुत ही विशेष रूप से समस्या के साथ डिजाइन किया गया था। ये एक निश्चित आकार के सरणी का उपयोग करते थे, और एक नल-टर्मिनेटर का उपयोग केवल तभी किया जाता था जब फ़ाइलनाम सरणी से छोटा था।

यही दो विषमताओं के पीछे है strncpy():

  • यदि यह पूरी तरह से भरा हुआ है तो यह गंतव्य पर एक शून्य-टर्मिनेटर नहीं डालता है; तथा
  • यह हमेशा पूरी तरह से गंतव्य को भरता है, यदि आवश्यक हो तो nuls के साथ।

एक "सुरक्षित" के लिए strcpy() " के लिए, आप इस तरह से उपयोग करना बेहतर समझते हैं strncat():

वह हमेशा परिणाम को शून्य करेगा, और आवश्यकता से अधिक कॉपी नहीं करेगा।


लेकिन, निश्चित रूप से, strncpy हमेशा वह नहीं होता जो आप चाहते हैं: strncpy गंतव्य बफ़र आकार जोड़ने और करने के लिए वर्णों की अधिकतम संख्या स्वीकार करता है ... लेकिन यह केवल एक छोटी सी बात है, इसलिए संभवतः जब तक आप एक मुद्दा नहीं होंगे एक स्ट्रिंग को दूसरे पर बदलने की कोशिश कर रहा हूँ।
डेविड वोलेवर 23

मुझे इसका कारण नहीं पता था, और यह बहुत ही प्रासंगिक है कि मैं एटीएम पर क्या काम कर रहा हूं।
मैट जॉइनर

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

1
हमें dest[0] = '\0';strncat कॉल से पहले लिखने की आवश्यकता क्यों है ? क्या आप समझाना चाहेंगे सर?
एसएन

4
@ एसएनआरआर: strncat()गंतव्य स्ट्रिंग के अंत में स्रोत स्ट्रिंग को सम्मिलित करता है। हम बस स्रोत स्ट्रिंग को गंतव्य पर कॉपी करना चाहते हैं, इसलिए हम पहले गंतव्य को खाली स्ट्रिंग पर सेट करते हैं - यही वह dest[0] = '\0';करता है।
कैफे

34

जबकि मैं पीछे के इरादे को जानता हूं strncpy, यह वास्तव में एक अच्छा कार्य नहीं है। दोनों से बचें। रेमंड चेन बताते हैं

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

यह भी देखें कि क्यों असुरक्षित है असुरक्षित?


27

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

  • यदि आप अपने स्ट्रिंग और बफर की लंबाई जानते हैं, तो स्ट्रेंची का उपयोग क्यों कर रहे हैं? यह कम से कम कंप्यूटिंग शक्ति की बर्बादी है (बेकार 0 जोड़कर)
  • यदि आप लंबाई नहीं जानते हैं, तो आप चुपचाप अपने तारों को काटते हुए जोखिम लेते हैं, जो कि एक अतिप्रवाह से बेहतर नहीं है

मुझे लगता है कि यह strncpy के लिए एक अच्छा विवरण है, इसलिए मैंने इसे वोट दिया है। strncpy में परेशानियों का एक सेट है। मुझे लगता है कि यही कारण है कि जैसे glib यह अपने स्वयं के एक्सटेंशन है। और हाँ यह दुर्भाग्यपूर्ण है कि आपको प्रोग्रामर के रूप में सभी सरणियों के आकार के बारे में पता होना चाहिए। डिकेंस को स्ट्रिंग के रूप में 0 टर्मिनेट किया गया है, इससे हम सभी को बहुत महंगा पड़ा है ...
फ्रेडरिक

1
तय-प्रारूप फ़ाइलों में डेटा संग्रहीत करते समय शून्य-गद्देदार तार बहुत आम हैं। यह सुनिश्चित करने के लिए, डेटाबेस इंजन और एक्सएमएल जैसी चीजों की लोकप्रियता, उपयोगकर्ता की अपेक्षाओं को विकसित करने के साथ, 20 साल पहले की तुलना में फिक्स्ड-फॉर्मेट फाइलें कम आम हैं। बहरहाल, इस तरह की फाइलें अक्सर डेटा स्टोर करने का सबसे अधिक समय के लिए कारगर साधन हैं। जब किसी रिकॉर्ड में डेटा की अपेक्षित और अधिकतम लंबाई के बीच भारी असमानता को छोड़कर, यह एक रिकॉर्ड को पढ़ने के लिए बहुत तेजी से एक एकल हिस्सा है जिसमें कई अप्रयुक्त डेटा शामिल हैं, जो रिकॉर्ड को कई विखंडों में विभाजित पढ़ने के बजाय है।
सुपरकाट

बस विरासत कोड का रखरखाव किया, जो g_strlcpy () का उपयोग करता था, इसलिए पैडिंग अक्षमताओं को नहीं झेलता, लेकिन निश्चित रूप से, स्थानांतरित किए गए बाइट्स की गिनती बनाए नहीं रखी गई थी, इसलिए कोड चुपचाप परिणाम को छोटा कर रहा था।
user2548100

21

आप strlcpy()जो खोज रहे हैं वह फ़ंक्शन है जो हमेशा 0 के साथ स्ट्रिंग को समाप्त करता है और बफर को इनिशियलाइज़ करता है। यह ओवरफ्लो का पता लगाने में भी सक्षम है। केवल समस्या, यह (वास्तव में) पोर्टेबल नहीं है और केवल कुछ प्रणालियों (बीएसडी, सोलारिस) पर मौजूद है। इस फ़ंक्शन के साथ समस्या यह है कि यह कीड़े के एक और डिब्बे को खोलता है जैसा कि चर्चाओं द्वारा देखा जा सकता है http://en.wikipedia.org/wiki/Strlcpy

मेरी निजी राय है कि यह strncpy()और की तुलना में अधिक उपयोगी है strcpy()। इसका प्रदर्शन बेहतर है और यह एक अच्छा साथी है snprintf()। जिन प्लेटफार्मों में यह नहीं है, उन्हें लागू करना अपेक्षाकृत आसान है। (एक आवेदन के विकास के चरण के लिए मैं इन दो फ़ंक्शन ( snprintf()और strlcpy()) को एक फंसाने वाले संस्करण के साथ स्थानापन्न करता हूं जो बफर ओवरफ्लो या ट्रंकेशन पर प्रोग्राम को बेरहमी से गर्भपात करता है। यह जल्दी से सबसे खराब अपराधियों को पकड़ने की अनुमति देता है। खासकर यदि आप किसी अन्य से कोडबेस पर काम करते हैं। ।

संपादित करें: strlcpy()आसानी से लागू किया जा सकता है:


3
आप लिख सकते हैं कि strlcpy लिनक्स और विंडोज के अलावा हर चीज पर उपलब्ध है! हालांकि, यह बीएसडी लाइसेंस प्राप्त है, इसलिए आप इसे अपने पुस्तकालयों में से एक में गिरा सकते हैं और वहां से इसका उपयोग कर सकते हैं।
माइकल वैन डेर वेस्टहुइज़न

आप के लिए एक परीक्षण जोड़ने के लिए dstsize > 0और अगर यह नहीं है कुछ भी नहीं करना चाहते हो सकता है।
चकरली

हाँ तुम सही हो। मैं चेक को जोड़ दूंगा क्योंकि इसके बिना गंतव्य बफर पर लंबाई की dstsizeगति बढ़ जाएगी और इसे बह निकला। memcpylen
पैट्रिक शाल्टर

अच्छा समाधान को बढ़ावा देने के लिए एक प्लस। अधिक लोगों को अकड़ के बारे में जानने की आवश्यकता है क्योंकि हर कोई इसे खराब तरीके से रोकता है।
आरपी

@MichaelvanderWesthuizen यह लिनक्स पर उपलब्ध है, सिर्फ ग्लिबक में नहीं। अधिक जानकारी के लिए अपने जवाब देखें (1) (2) (3)
आरएसपी

3

strncpy()समारोह को सुरक्षित एक है: आप अधिकतम लंबाई गंतव्य बफर स्वीकार कर सकते हैं पारित करने के लिए की है। अन्यथा यह हो सकता है कि स्रोत स्ट्रिंग सही ढंग से 0 समाप्त नहीं हुई है, जिस स्थिति में strcpy()फ़ंक्शन गंतव्य को अधिक वर्ण लिख सकता है, कुछ भी भ्रष्ट कर सकता है जो गंतव्य बफर के बाद स्मृति में है। यह कई कारनामों में इस्तेमाल होने वाली बफर-ओवररन समस्या है

POSIX API फ़ंक्शंस के लिए भी, read()जो टर्मिनेटिंग 0 को बफर में नहीं डालता है, लेकिन पढ़े गए बाइट्स की संख्या देता है, आप या तो मैन्युअल रूप से 0 डालेंगे, या इसका उपयोग करके कॉपी कर सकते हैं strncpy()

अपने उदाहरण कोड में, indexवास्तव में एक सूचकांक नहीं है, लेकिन एक count- यह बताता है कि कैसे कई पात्रों ज्यादा से ज्यादा गंतव्य के लिए स्रोत से कॉपी करने के लिए। यदि स्रोत के पहले n बाइट्स के बीच कोई नल बाइट नहीं है, तो गंतव्य में रखी स्ट्रिंग को समाप्त नहीं किया जाएगा


1

strncpy स्रोत के आकार के लिए '\ 0' के साथ गंतव्य को भरता है, अंततः गंतव्य का आकार छोटा होता है ...।

मैनपेज:

यदि src की लंबाई n से कम है, तो strncpy () नल बाइट्स के साथ भाग्य के शेष को पैड करता है।

और न केवल शेष ... इसके बाद भी जब तक कि एन अक्षर तक नहीं पहुंच जाते। और इस प्रकार आपको एक अतिप्रवाह मिलता है ... (मैन पेज कार्यान्वयन देखें)


3
strncpy स्रोत के आकार के लिए '\ 0' के साथ गंतव्य को भरता है, आखिरकार गंतव्य का आकार छोटा है .... मुझे डर है कि यह कथन गलत और भ्रामक है: strncpyगंतव्य को '\ 0' के साथ भरता है। आकार तर्क, यदि स्रोत की लंबाई कम है। आकार तर्क स्रोत का आकार नहीं है, स्रोत से कॉपी करने के लिए अधिकतम वर्ण नहीं है, क्योंकि यह अंदर है strncat, यह गंतव्य का आकार है।
चकरली

@ अक्रली: बिल्कुल। strncpyअन्य कॉपी ऑपरेशंस पर एक फायदा यह है कि यह गारंटी देता है कि पूरा गंतव्य लिखा जाएगा। चूंकि कंपाइलर कुछ अनिश्चित मानों वाली संरचनाओं की नकल करते समय "रचनात्मक" प्राप्त करने की कोशिश कर सकते हैं, यह सुनिश्चित करते हुए कि संरचनाओं के भीतर किसी भी वर्ण सरणियों को पूरी तरह से लिखा गया है, "आश्चर्य" को रोकने का सबसे सरल तरीका हो सकता है।
सुपरकैट

@ सुपरकैट: इस विशिष्ट मामले के लिए एक बहुत छोटा लाभ ... लेकिन कॉल के बाद गंतव्य को पैच किया जाना चाहिए strncpy शून्य समाप्ति सुनिश्चित लिए : strncpy(dest, src, dest_size)[dest_size - 1] = '\0';
चकरली

@chqrlie: एक अनुगामी नल बाइट की आवश्यकता होगी या नहीं, यह इस बात पर निर्भर करेगा कि डेटा को किसका प्रतिनिधित्व करना है। किसी संरचना के भीतर शून्य-टर्म डेटा के बजाय शून्य-गद्देदार का उपयोग करना उतना सामान्य नहीं है जितना कि इसका उपयोग किया जाता है, लेकिन यदि उदाहरण के लिए ऑब्जेक्ट-फ़ाइल स्वरूप 8-बाइट अनुभाग नामों का उपयोग करता है, तो सक्षम होने के लिएchar[8] संरचना के भीतर चीजों को संभालने में सक्षम होना 8 वर्णों का उपयोग करने की तुलना में अच्छा हो सकता है, char[8]लेकिन केवल 7 वर्णों को संभालने में सक्षम है, या एक स्ट्रिंग को char[9]बफर में कॉपी करने और फिर memcpyइसे गंतव्य पर ले जाने के लिए।
सुपरकैट

@chqrlie: स्ट्रिंग्स के साथ काम करने वाले अधिकांश कोड को पता होना चाहिए कि वे कितने समय तक हो सकते हैं, और charजब तक वे एक शून्य हिट नहीं करते हैं, तब तक पॉइंटर्स के साथ नेत्रहीन रूप से नहीं चलना चाहिए । केवल बात यह है कि शून्य समाप्त तार स्ट्रिंग शाब्दिक है के लिए वास्तव में अच्छा कर रहे हैं, और यहां तक कि वहाँ एक चर लंबाई एन्कोड उपसर्ग शायद बेहतर होगा। लगभग सब कुछ के लिए, यह बेहतर होगा तार या तो लंबाई के साथ उपसर्ग की है, या एक विशेष उपसर्ग किया जाए जो यह दर्शाता है कि char*वास्तव में ऐसा कुछ है struct stringInfo {char header[4]; char *realData; size_t length; size_t size;}
सुपरकैट

-1

इसका उपयोग कई अन्य परिदृश्यों में किया जा सकता है, जहां आपको अपने मूल स्ट्रिंग के केवल एक हिस्से को गंतव्य पर कॉपी करने की आवश्यकता होती है। Strncpy () का उपयोग करके आप मूल स्ट्रिंग के सीमित भाग की प्रतिलिपि बना सकते हैं जैसा कि strcpy () द्वारा विरोध किया गया है। मुझे लगता है कि आपने जो कोड डाला है वह publib.boulder.ibm.com से आता है ।


-1

यह हमारी आवश्यकता पर निर्भर करता है। विंडोज़ उपयोगकर्ताओं के लिए

जब भी हम संपूर्ण स्ट्रिंग को कॉपी नहीं करना चाहते हैं या हम केवल n वर्णों की प्रतिलिपि बनाना चाहते हैं, तो हम strncpy का उपयोग करते हैं। लेकिन strcpy शून्य चरित्र को समाप्त करने सहित पूरे स्ट्रिंग की प्रतिलिपि बनाता है।

ये लिंक आपको स्ट्रैची और स्ट्रैन्की और जहाँ हम उपयोग कर सकते हैं, के बारे में अधिक जानने में मदद करेंगे।

के बारे में

अकड़ के बारे में


-8

strncpy strcpy का एक सुरक्षित संस्करण है, इस तथ्य के रूप में कि आपको कभी भी strcpy का उपयोग नहीं करना चाहिए क्योंकि इसकी संभावित बफर अतिप्रवाह भेद्यता है जो आपको सिस्टम को सभी प्रकार के हमलों के लिए असुरक्षित बनाती है।


6
देखें lysator.liu.se/c/rat/d11.html : स्ट्रैन्की फंक्शन strncpy को शुरू में सी लाइब्रेरी में डायरेक्टरी एंट्रीज जैसे स्ट्रक्चर्स में तय लंबाई के नाम फील्ड्स से निपटने के लिए पेश किया गया था। इस तरह के फ़ील्ड का उपयोग स्ट्रिंग्स के समान नहीं किया जाता है: अनुगामी नल अधिकतम लंबाई वाले क्षेत्र के लिए अनावश्यक है, और छोटे नामों के लिए अनुगामी बाइट्स सेट करने से कुशल फ़ील्ड-वार तुलनाओं का आश्वासन मिलता है। strncpy मूल रूप से एक `` बंधे हुए strcpy, '' के द्वारा नहीं है और समिति ने इस तरह के उपयोग के लिए बेहतर ढंग से फ़ंक्शन को बदलने के बजाय मौजूदा अभ्यास को पहचानना पसंद किया है।
सिनान Augnür
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.