अपनी पुस्तक द प्रैक्टिस ऑफ प्रोग्रामिंग (जो पढ़ने में अच्छी तरह से लायक है) में, कार्निगन और पाइक इस समस्या पर चर्चा करते हैं, और वे इसे फ़ंक्शन snprintf()
के scanf()
परिवार को पारित करने के लिए सही बफर आकार के साथ स्ट्रिंग बनाने के लिए उपयोग करके हल करते हैं। प्रभाव में:
int scanner(const char *data, char *buffer, size_t buflen)
{
char format[32];
if (buflen == 0)
return 0;
snprintf(format, sizeof(format), "%%%ds", (int)(buflen-1));
return sscanf(data, format, buffer);
}
ध्यान दें, यह अभी भी 'बफर' के रूप में दिए गए आकार के इनपुट को सीमित करता है। यदि आपको अधिक स्थान की आवश्यकता है, तो आपको मेमोरी आवंटन करना होगा, या एक गैर-मानक लाइब्रेरी फ़ंक्शन का उपयोग करना होगा जो आपके लिए मेमोरी आवंटन करता है।
ध्यान दें कि scanf()
फ़ंक्शन के परिवार का POSIX 2008 (2013) संस्करण m
स्ट्रिंग इनपुट के लिए एक प्रारूप संशोधक (एक असाइनमेंट-आवंटन चरित्र) का समर्थन करता है (%s
, %c
, %[
)। एक char *
तर्क लेने के बजाय , यह एक char **
तर्क लेता है , और इसे पढ़े जाने वाले मूल्य के लिए आवश्यक स्थान आवंटित करता है:
char *buffer = 0;
if (sscanf(data, "%ms", &buffer) == 1)
{
printf("String is: <<%s>>\n", buffer);
free(buffer);
}
यदि sscanf()
फ़ंक्शन सभी रूपांतरण विशिष्टताओं को पूरा करने में विफल रहता है, तो सभी मेमोरी जो इसे समान %ms
रूपांतरणों के लिए आवंटित की जाती है, फ़ंक्शन वापस आने से पहले मुक्त हो जाती है।
buflen-1
- धन्यवाद। फिर आपको अहस्ताक्षरित अंडरफ़्लो (बल्कि बड़ी संख्या में लपेटना) के बारे में चिंता करना होगा, इसलिएif
परीक्षण। मैं व्यथित रूप से इसे बदलने की कोशिश कर रहा हूँassert()
, अगर किसी के साथ यहassert()
पहले होif
कि विकास के दौरान आग लग जाए, तो कोई भी लापरवाह हो सकता है। मैंने ध्यान से दस्तावेज़ीकरण की समीक्षा नहीं की है कि%0s
इसका क्या मतलब हैsscanf()
- परीक्षण बेहतर हो सकता हैif (buflen < 2)
।