दिलचस्प पोस्ट
टोटल में HttpRequest अधिकतम स्वीकार्य आकार? गैर अवरुद्ध कार्यकर्ता – फ़ाइल प्रतिलिपि में बाधा डालें UIView में ओरिएंटेशन UIWindow में जोड़ा गया फ्रैग्मेंटपेगर एडाप्टर और फ्रैगमेंटस्टेट पेजर एडेप्टर के बीच का अंतर ऑरेकल में एक संग्रहीत कार्यविधि के बिना एक पंक्ति में कितनी पंक्तियां एकत्रित की जा सकती हैं? मुझे एक SQL सर्वर प्रतिकृति प्रोजेक्ट पर "गलत प्रारूप के साथ प्रोग्राम लोड करने का प्रयास किया गया" त्रुटि मिलती है I एक मौजूदा जावास्क्रिप्ट पुस्तकालय से आप एक .d.ts "typings" परिभाषा फ़ाइल कैसे बना सकते हैं? Angular2 – त्रुटि अगर {{object.field}} मौजूद है, तो जांच नहीं है लोग C ++ में इतना क्यों __ (डबल अंडरस्कोर) का उपयोग करते हैं वैकल्पिक के लिए उपयोग नए टैबलेआउट सूचक रंग और ऊंचाई कैसे बदलूए स्विफ्ट – एन्कोड यूआरएल कमांड चलाएं और स्टडआउट, स्टडरर को अलग-अलग रीयल टाइम में लें जैसे टर्मिनल में मैं एएसपी.नेट एमवीसी में कैसे ठीक से 404 को संभाल सकता हूं? प्रतिक्रिया में setState Async या सिंक है

सी में हो जाता है () फ़ंक्शन

मुझे फिर से मदद की ज़रूरत है! मैंने सोचा कि यह gets() फ़ंक्शन का उपयोग करने के लिए बहुत अच्छा है, क्योंकि यह scanf() जिसमें मैं सफेद स्थान के साथ एक इनपुट प्राप्त कर सकता था लेकिन मैंने एक धागे ( छात्र जानकारी फ़ाइल हैंडलिंग ) में पढ़ा है कि इसका उपयोग करना अच्छा नहीं है क्योंकि उनके अनुसार, यह बफर ओवरफ्लो बनाने के लिए एक शैतान का टूल है (जिसे मुझे समझ में नहीं आ रहा है)

यदि मैं gets() फ़ंक्शन का उपयोग करता हूं, तो मैं ऐसा कर सकता हूं। अपना नाम दर्ज करें: Keanu Reeves

अगर मैं scanf() उपयोग करता हूं, तो मैं केवल यह कर सकता था। अपना नाम दर्ज करें: Keanu

इसलिए मैं उनकी सलाह को ध्यान में रखता हूं और मेरी सभी gets() कोड को fgets() के साथ बदल देता हूं। समस्या यह है कि मेरे कुछ कोड अब काम नहीं कर रहे हैं … क्या gets() और fgets() जो कि पूरी लाइन को पढ़ सकता है और जो कि सफेद स्थान की उपेक्षा करता है, के अलावा कोई भी कार्य है

वेब के समाधान से एकत्रित समाधान "सी में हो जाता है () फ़ंक्शन"

यह बफर ओवरफ्लो बनाने के लिए शैतान का टूल है

चूंकि कोई लंबाई पैरामीटर नहीं लेता है, यह नहीं जानता कि आपका इनपुट बफ़र कितना बड़ा है यदि आप 10-वर्ण बफर में प्रवेश करते हैं और उपयोगकर्ता 100 वर्णों में प्रवेश करता है – ठीक है, आप बिंदु प्राप्त करते हैं।

fgets एक सुरक्षित विकल्प gets क्योंकि यह बफर लंबाई को पैरामीटर के रूप में लेता है, ताकि आप इसे इस तरह से कॉल कर सकें:

 fgets(str, 10, stdin); 

और इसे अधिकतम 9 वर्णों में पढ़ा जाएगा।

समस्या अब मेरे कुछ कोड अब और काम नहीं कर रहे हैं

यह संभवतया है क्योंकि fgets आपके बफ़र में अंतिम न्यूलाइन ( \n ) वर्ण भी संग्रहीत करता है – अगर आपका कोड इस की अपेक्षा नहीं कर रहा है, तो आपको मैन्युअल रूप से इसे निकालना चाहिए:

 int len = strlen(str); if (len > 0 && str[len-1] == '\n') str[len-1] = '\0'; 

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

1 9 88 में जारी पहली व्यापक कीड़े में से एक, इंटरनेट gets() इंटरनेट gets() पर खुद को उत्तेजित करने के लिए इस्तेमाल किया gets() । पीटर वैन डेर लिंडेन द्वारा विशेषज्ञ सी प्रोग्रामिंग से यहां एक दिलचस्प अंश है, जिसमें चर्चा की गई है कि यह कैसे काम करता है:

अर्ली बग () इंटरनेट का कीड़ा ()

सी की समस्याएं सिर्फ भाषा तक सीमित नहीं हैं मानक पुस्तकालय में कुछ दिनचर्या असुरक्षित शब्दों हैं। यह नाटकीय रूप से नवंबर 1 9 88 में कृमि कार्यक्रम द्वारा प्रदर्शित किया गया था जो कि इंटरनेट नेटवर्क पर हजारों मशीनों के माध्यम से कूड़ा हुआ था। जब धुआं साफ हो गया और जांच पूरी हो गई, तो यह निर्धारित किया गया कि एक तरह की कीड़ा ने finger में एक कमजोरी के माध्यम से प्रचार किया था, जो उस नेटवर्क के प्रश्नों को स्वीकार करता है जो वर्तमान में लॉग इन है। finger डेमन, in.fingerd , मानक I / O दिनचर्या का उपयोग किया gets()

नाममात्र का काम gets() एक धारा से एक स्ट्रिंग में पढ़ना है। कॉलर कहता है कि आने वाले अक्षर कहाँ ले जाएंगे लेकिन gets() बफर स्थान की जांच नहीं करता; वास्तव में, यह बफर स्थान की जांच नहीं कर सकता यदि कॉलर स्टैक पर एक सूचक प्रदान करता है, और बफर स्थान से अधिक इनपुट, gets() स्टैक पर खुशी से अधिलेखित करता है finger डेमॉन में कोड था:

 main(argc, argv) char *argv[]; { char line[512]; ... gets(line); 

यहां, line 512-बाइट सरणी है जिसे स्टाक पर स्वचालित रूप से आवंटित किया जाता है। जब कोई उपयोगकर्ता finger से अधिक इनपुट प्रदान करता है, तो gets() नियमित इसे स्टैक पर रखेगा। ज्यादातर आर्किटेक्चर स्टैक के बीच में एक बड़ा प्रविष्टि के साथ मौजूदा प्रविष्टि को ओवरराइट करने के लिए कमजोर हैं, जो पड़ोसी प्रविष्टियों को भी ओवरराइट करता है। आकार और अनुमति के लिए प्रत्येक स्टैक एक्सेस की जांच की लागत सॉफ्टवेयर में निषेधात्मक होगी। एक ज्ञानी पुरुष अपराधी तर्क स्ट्रिंग में सही बायनरी पैटर्न को छँटाकर स्टैक पर प्रक्रिया सक्रियण रिकॉर्ड में वापसी का पता संशोधित कर सकता है। इससे निष्पादन के प्रवाह को वापस नहीं लौटाया जाएगा, जहां से वह वापस नहीं आया था, बल्कि एक विशेष अनुदेश अनुक्रम (जो भी स्टैक पर ध्यानपूर्वक जमा किया गया था execv() को चलाया जाता है जो कि execv() को शेल के साथ चलने वाली छवि को प्रतिस्थापित करता है। वॉयला, अब आप finger डेमॉन की बजाय एक रिमोट मशीन पर एक शेल से बात कर रहे हैं, और आप वायरस की एक प्रति दूसरी मशीन में खींचकर आदेश जारी कर सकते हैं।

विडंबना यह है कि, gets() नियमित एक अप्रचलित कार्य है जो पोर्टेबल I / O लाइब्रेरी के पहले संस्करण के साथ संगतता प्रदान करता है, और एक दशक पहले मानक I / O द्वारा प्रतिस्थापित किया गया था। मैन पेज भी जोरदार अनुशंसा करता है कि fgets() हमेशा इसके बजाय उपयोग किया जाता है fgets() नियमित वर्णों की संख्या पर एक सीमा निर्धारित करता है, इसलिए यह बफर के आकार से अधिक नहीं होगा। finger डेमॉन को दो-लाइन फिक्स के साथ सुरक्षित बनाया गया था जो बदले:

 gets(line); 

लाइनों द्वारा:

 if (fgets(line, sizeof(line), stdin) == NULL) exit(1); 

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

आप इस प्रश्न को देख सकते हैं: सुरक्षित विकल्प gets() कई उपयोगी उत्तर हैं

आपको इसके बारे में अधिक सटीक होना चाहिए कि आपका कोड fgets() साथ क्यों काम नहीं करता जैसा कि दूसरे प्रश्न में दिए गए उत्तर में बताया गया है, आपको उस न्यूलाइन से निपटना होगा जो gets() को छोड़ देता है

Scanf का उपयोग करके सभी शब्द पढ़ने के लिए आप इसे इस तरह से कर सकते हैं

उदाहरण :

 printf("Enter name: "); scanf("%[^\n]s",name); //[^\n] is the trick 

आप scanf को नकल करने के लिए उपयोग कर सकते हैं। यह काफी हालांकि नहीं है।

 #include <stdio.h> #define S_HELPER(X) # X #define STRINGIZE(X) S_HELPER(X) #define MAX_NAME_LEN 20 int flushinput(void) { int ch; while (((ch = getchar()) != EOF) && (ch != '\n')) /* void */; return ch; } int main(void) { char name[MAX_NAME_LEN + 1] = {0}; while (name[0] != '*') { printf("Enter a name (* to quit): "); fflush(stdout); scanf("%" STRINGIZE(MAX_NAME_LEN) "[^\n]", name); /* safe gets */ if (flushinput() == EOF) break; printf("Name: [%s]\n", name); puts(""); } return 0; } 

यदि आप sscanf साथ fgets और पार्सिंग (यदि आवश्यक हो) के साथ पढ़ने से बेहतर हो


Scanf कॉल और आसपास के कोड को समझाते हुए संपादित करें

scanf की "% [" रूपांतरण विनिर्देशन अधिकतम क्षेत्र की चौड़ाई स्वीकार करता है जिसमें नल टर्मिनेटर शामिल नहीं होता है तो इनपुट को रखने के लिए सरणी scanf के साथ पढ़ने की तुलना में 1 और अधिक वर्ण होना चाहिए।

ऐसा करने के लिए केवल एक एकल स्थिरांक के साथ मैंने STRINGIZE मैक्रो का इस्तेमाल किया। इस मैक्रो के साथ मैं एक स्ट्रिंग (स्पेसिफायर के लिए) के रूप में एक # परिभाषित स्थिर दोनों को एक सरणी आकार (चर परिभाषा के लिए) के रूप में उपयोग कर सकते हैं।

एक और पहलू है जो उल्लेख के योग्य है: flushinput । यदि उपयोग gets , तो सभी डेटा को स्मृति में लिखा जाता है (बफर ओवरफ्लो भी होता है, लेकिन नएलाइन को शामिल नहीं किया जा सकता है) यह नकल करने के लिए, scanf में सीमित वर्णों की संख्या पढ़ी जाती है, लेकिन इसमें नई लाइन शामिल नहीं है, और इसके विपरीत नहीं, इनपुट बफर में नई लाइन रखती है ताकि नई लाइन को निकाला जाना चाहिए और यही flushinput करता है।

शेष कोड मुख्य रूप से एक परीक्षण वातावरण स्थापित करने के लिए था।

आप scanf() साथ एक से अधिक फ़ील्ड पढ़ सकते हैं, ताकि आप ऐसा कर सकते हैं:

 scanf("%s %s\n", first_name, last_name); 

हालांकि, मुझे लगता है कि यह एक स्ट्रिंग को पढ़ने के लिए बेहतर होगा और फिर इसे खुद को विभाजित करेगा क्योंकि उन्होंने पहले नाम, या प्रथम / मध्य / अंतिम में प्रवेश नहीं किया हो सकता है

क्या आप fgets() साथ कर रहे हैं समस्याएं हैं?

gets() समस्या gets() यह है कि यह उपयोगकर्ता के रूप में कई पात्रों के रूप में लौटाता है – जैसे आप कॉलर का इस पर कोई नियंत्रण नहीं है। तो आप 80 वर्णों को आवंटित कर सकते हैं, उपयोगकर्ता 100 वर्ण टाइप कर सकता है और पिछले 20 को आपके द्वारा आवंटित की गई स्मृति के अंत में लिखा जाएगा, कौन जानता है कि कौन क्या जानता है