c - यदि हम "% s" युक्त स्ट्रिंग को प्रिंट करते हैं तो आउटपुट क्या होगा?




printf undefined (4)

अपरिभाषित व्यवहार होगा। :)

स्ट्रिंग शाब्दिक %s इस भाग को फ़ंक्शन द्वारा एक प्रारूप विनिर्देशक के रूप में माना जाता है।

सी स्टैंडर्ड (7.21.6.1 द फ़र्प्रिंट फंक्शन) से

  1. ... यदि प्रारूप के लिए अपर्याप्त तर्क हैं, तो व्यवहार अपरिभाषित है।

यदि आप स्ट्रिंग को "hi%s" आउटपुट करना चाहते हैं तो आपको "hi%%s" जैसे शाब्दिक को परिभाषित करना चाहिए।

यहाँ एक प्रदर्शन कार्यक्रम है

#include <stdio.h>

int main(void) 
{
    char *ptr = "hi%%s";

    printf( ptr );

    return 0;
}

इसका आउटपुट है

hi%s

मैं जानना चाहता हूं कि यदि हम एक स्ट्रिंग प्रिंट करते हैं तो क्या परिणाम होगा जो इसकी सामग्री में "% s" है?

मैंने इसे "हाय% s" के रूप में छापने की कोशिश की।

char *ptr="hi%s";
printf(ptr);

मुझे उम्मीद थी कि आउटपुट "हाय" होगा। लेकिन मुझे यह "हाय हाय% s" के रूप में मिला।

"हाय हाय% s"


आप "एक स्ट्रिंग को मुद्रित नहीं कर रहे हैं जिसकी सामग्री में %s है"। आप इस तरह की स्ट्रिंग को स्वरूप स्ट्रिंग के रूप में printf कर रहे हैं, और प्रारूप क्षेत्र के लिए एक मिलान तर्क के बिना ऐसा करने से, आपके कार्यक्रम में अपरिभाषित व्यवहार होता है । प्रिंट करने के लिए पहला तर्क वह स्ट्रिंग नहीं है जिसे आप प्रिंट करना चाहते हैं। यह एक प्रारूप स्ट्रिंग है जो नियंत्रित करता है कि शेष तर्कों को कैसे व्याख्या / रूपांतरित किया जाता है, और जिसमें उन्हें विलय करने के लिए शाब्दिक पाठ भी हो सकता है।

"एक स्ट्रिंग को प्रिंट करना जिसकी सामग्री में %s है" (जहां ptr उस स्ट्रिंग को इंगित करता है, जैसा कि आपके प्रश्न में है) printf("%s", ptr) या puts(ptr) द्वारा पूरा किया जा सकता है।


जैसा कि अन्य उत्तर में उल्लेख किया गया है, आप जो अपरिभाषित व्यवहार कर रहे हैं, क्योंकि आप दिए गए प्रारूप विनिर्देशक के लिए पर्याप्त तर्क के बिना printf को बुला रहे हैं। आपके मामले में आपको जंक आउटपुट मिला है, लेकिन आपका कार्यक्रम आसानी से दुर्घटनाग्रस्त हो सकता है।

इस पर विस्तार करने के लिए, कोड जो इस तरह दिखता है:

printf(ptr);

लगभग हमेशा गलत है। यदि वह स्ट्रिंग जिसे ptr इंगित करता है, तो उपयोगकर्ता द्वारा किसी भी तरह से नियंत्रित किया जा सकता है, आप स्वयं को एक स्ट्रिंग स्ट्रिंग भेद्यता के लिए खोल सकते हैं। उपयोगकर्ता %s , %x , आदि का उपयोग करके विशेष रूप से तैयार किए गए स्ट्रिंग की आपूर्ति कर सकता है जो मेमोरी की सामग्री को डंप कर सकता है और संवेदनशील डेटा को उजागर कर सकता है, या %n का उपयोग करने वाला एक स्ट्रिंग जो मेमोरी में लिख सकता है और एक हमलावर को आपके प्रोग्राम को लेने की अनुमति दे सकता है।

कई स्थिर विश्लेषक एक चेतावनी फेंक देंगे यदि printf लिए पहला तर्क इस कारण से एक स्ट्रिंग स्थिर नहीं है।


जैसा कि अन्य उत्तर में निर्दिष्ट है, एक अपरिभाषित व्यवहार होगा।

इस संदर्भ में अपरिभाषित व्यवहार का क्या अर्थ है: जब printf को एन स्पेसिफिकर्स की संख्या के साथ एक स्ट्रिंग प्राप्त होती है (जैसे कि% s) तो यह स्ट्रिंग के अलावा फ़ंक्शन के लिए एन मापदंडों की संख्या को पारित करने की उम्मीद करने वाला है। इसलिए, जब आपके पास इस printf("hi%s") तरह एक बयान होता है, तो फ़ंक्शन ऐसा व्यवहार करेगा जैसे कि आपने एक पैरामीटर पारित किया है (इस मामले में दूसरा पैरामीटर एक चार * होना चाहिए) भले ही ऐसा न हो। फ़ंक्शन बस स्टैक पर अगला मान प्राप्त करने जा रहा है जो इस मामले में कुछ रद्दी मूल्य है। तब फ़ंक्शन इस जंक मान को टाल देगा और इसे वर्णों के बफर के रूप में मानेगा। इस व्यवहार के अपरिभाषित होने के कारणों में यह नहीं बताया गया है कि स्टैक पर जंक मूल्य क्या हो सकता है।

संभावित नतीजे

  1. स्टैक पर रद्दी मान 0 है -> रद्दी मान को अलग किए जाने पर विभाजन दोष।

  2. स्टैक पर जंक वैल्यू एक वैध मेमोरी एड्रेस होता है -> मेमोरी लोकेशन पर बाइट्स को स्ट्रिंग में डाला जाता रहेगा (इस मामले में "hi" में जोड़ा जाता है) जब तक कि वैल्यू 0 का एक बाइट सामने नहीं आता है या एक विभाजन नहीं होता है गलती होती है।

  3. स्टैक पर जंक मान 0 नहीं है, लेकिन एक मान्य मेमोरी लोकेशन नहीं है -> जंक वैल्यू को डिरेल होने पर सेगमेंटेशन फॉल्ट।

समान स्थिति उत्पन्न करना कोड के नीचे का भाग printf("hi%s") समान स्थिति है

void foo() {
   char * myJunkValue;  // Since not a global/static variable, this is not guaranteed to be 0
   printf(myJunkValue); // Undefined behavior
}




c-strings