गैर-शून्य समाप्त स्ट्रिंग के साथ प्रिंटफ़ का उपयोग करना


107

मान लीजिए कि आपके पास एक स्ट्रिंग है जिसे nullसमाप्त नहीं किया गया है और आपको इसका सही आकार पता है, तो आप उस स्ट्रिंग को printfC में कैसे प्रिंट कर सकते हैं ? मुझे ऐसी विधि याद है, लेकिन मुझे अभी पता नहीं चला ...


9
में Cसंदर्भ, सभी स्ट्रिंग्स अशक्त समाप्त कर रहे हैं। उनके बिना अशक्त के चार के तार तार नहीं हैं ... वे चार के
सरण हैं


जवाबों:


174

प्रिंटफ के साथ एक संभावना है, यह इस प्रकार है:

printf("%.*s", stringLength, pointerToString);

कुछ भी कॉपी करने की आवश्यकता नहीं है, मूल स्ट्रिंग या बफर को संशोधित करने की कोई आवश्यकता नहीं है।


10
लेकिन वैसे भी यह खतरनाक है, किसी दिन इस स्ट्रिंग को% s के साथ
प्रिंट किया जाएगा

6
@ प्रमोद: जरूरी नहीं कि बफर बाहरी दुनिया के संपर्क में न हो। यह सिर्फ एक स्ट्रिंग के कुछ हिस्सों को प्रिंट करने के लिए बहुत उपयोगी है (जो शून्य से समाप्त हो सकता है, निश्चित रूप से)। यदि आप वास्तव में इसे क्रिया में देखना चाहते हैं, तो OpenSER / Kamailio SIP प्रॉक्सी पर एक नज़र डालें, जहाँ वे इस तकनीक के कारण सामान की नकल करने से बचते हैं (स्प्रिंट का उपयोग करके भी)।
DarkDust

6
एक और +1। मैं इसे प्यार करता हूँ जब मैं printfएक ~ दशक के बाद भी बुनियादी चीजों के बारे में बातें सीखता हूँ ... :)
हर्ट्ज़ेल गिनीज़

1
मेरे लिए यह बहुत उपयोगी है जब मुझे एक एपीआई (कुछ विंडोज़ एपीआई ऐसा करते हैं) से एक गैर-शून्य समाप्त स्ट्रिंग प्राप्त होता है और इसे 'उचित' तरीके से वापस करना पड़ता है। । तो:% करने के लिए लंबे जीवन * s (।! या% * एस जो भी रूपांतरण यूनिकोड कर देगा <-> आप के लिए सिंगल-बाइट;))
FrizzTheSnail

3
@ user1424739: आपके मामले में printf11 वर्णों तक प्रिंट होगा या जब तक उसका सामना NULL से नहीं होगा, जो भी पहले आएगा; आपके उदाहरण में NULL पहले आता है। अधिकतम लंबाई निर्दिष्ट करने से NULL का "एंड-ऑफ-स्ट्रिंग" अर्थ खो नहीं जाता है printf
DarkDust

29

यहां बताया गया है कि कैसे %.*sकाम करता है, और यह कहां निर्दिष्ट है।

प्रिंटफ टेम्पलेट स्ट्रिंग में रूपांतरण विनिर्देशों का सामान्य रूप है:

% [ param-no $] flags width [ . precision ] type conversion

या

% [ param-no $] flags width . * [ param-no $] type conversion

दूसरा रूप तर्क सूची से सटीक प्राप्त करने के लिए है:

आप '*' की शुद्धता भी बता सकते हैं। इसका मतलब यह है कि तर्क सूची में अगला तर्क (मुद्रित होने के लिए वास्तविक मूल्य से पहले) का उपयोग सटीक के रूप में किया जाता है। मान एक इंट होना चाहिए, और यदि यह नकारात्मक है तो इसे नजरअंदाज कर दिया जाना चाहिए।

-  glibc मैनुअल में आउटपुट रूपांतरण सिंटैक्स

के लिए %sस्ट्रिंग स्वरूपण, सटीक एक विशेष अर्थ नहीं है:

लिखने के लिए अधिकतम संख्या में वर्णों को इंगित करने के लिए एक सटीक निर्दिष्ट किया जा सकता है; अन्यथा स्ट्रिंग में वर्ण, लेकिन समाप्त करने योग्य अशक्त वर्ण को शामिल नहीं करते हुए आउटपुट स्ट्रीम में लिखे जाते हैं।

-  glibc मैनुअल में अन्य आउटपुट रूपांतरण

अन्य उपयोगी संस्करण:

  • "%*.*s", maxlen, maxlen, val सही-औचित्य, पहले रिक्त स्थान डालने;
  • "%-*.*s", maxlen, maxlen, val वाम-औचित्य होगा।

अगर मैं सही तरीके से समझूं, तो निम्न में से आउटपुट में अभी भी एक स्ट्रिंग ओवरफ्लो को रोकना होगा? "%-*.*s", padding, str_view.size(), str_view.data()
scx

20

आप stdout करने के लिए एक fwrite () का उपयोग कर सकते हैं!

fwrite(your_string, sizeof(char), number_of_chars, stdout);

इस तरह से आप पहले वर्ण (संख्या_ संख्या_ चर में परिभाषित संख्या) को एक फ़ाइल में आउटपुट करेंगे, इस मामले में stdout (मानक आउटपुट, आपकी स्क्रीन)!


2
बहुत मददगार जब आप तार और शून्य वाले एक लंबे बफर का निरीक्षण करना चाहते हैं!
एलिस्ट

13

printf("%.*s", length, string) काम नहीं करेगा।

इसका मतलब यूपी टू लेंथ बाइट्स या नल बाइट को प्रिंट करना है, जो भी पहले आए। यदि आपके गैर-शून्य-टर्मिनेटेड सरणी-ऑफ-चार में अशक्त बाइट्स शामिल हैं, तो लंबाई उन पर बंद हो जाएगी, और जारी नहीं रहेगी।


4
और यह ओपी के सवाल का जवाब कैसे है?
शहबाज

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

3
printf("%.5s", pointerToNonNullTerminatedString);

स्ट्रिंग की लंबाई 5 होगी।


1
#include<string.h> 
int main()
{
/*suppose a string str which is not null terminated and n is its length*/
 int i;
 for(i=0;i<n;i++)
 {
 printf("%c",str[i]);
 }
 return 0;
}

मैंने कोड को संपादित किया, अन्य तरीके से:

#include<stdio.h>
int main()
{
printf ("%.5s","fahaduddin");/*if 5 is the number of bytes to be printed and fahaduddin is the string.*/

return 0;

}

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

@DarkDust: केवल एक पैथोलॉजिकल मशीन बाइट को दंडित करेगी, जो शब्द सीमाओं से जुड़ी नहीं है। क्या आप शब्द के बारे में सोच रहे हैं कि शब्द सीमाओं से जुड़ा हुआ नहीं है? या कुछ प्राचीन घोसले बकवास या कुछ और?
आर .. गिटहब स्टॉप हेल्पिंग ICE

@ आर ..: यदि आप x86 मस्तिष्क-क्षतिग्रस्त और आउट-डेटेड मानते हैं, तो मैं बिल्कुल सहमत हूं। क्योंकि x86 में गैर-शब्द संरेखित मेमोरी को पढ़ने और लिखने के लिए जुर्माना है। तो एआरएम करता है। उदाहरण के लिए देखें यह प्रश्न या यह प्रश्न । बात यह है (अगर मुझे सही ढंग से समझ में आ गया है) उस डेटा को मेमोरी से शब्द-आकार के टुकड़ों में लिया गया है और सही बाइट प्राप्त करना एक और माइक्रो-ऑप है। कोई बड़ी बात नहीं है, लेकिन एक विशाल लूप में इससे फर्क पड़ सकता है।
DarkDust

@DarkDust: बाइट के लिए आप पूरी तरह से गलत हैं। आप बेंचमार्क क्यों नहीं करते? x86 में पूरी तरह से परमाणु बाइट संचालन होता है और हमेशा होता है। यह शब्द-आकार के विखंडन को नहीं उठाता (कैश स्तर को छोड़कर, जो बहुत बड़ा हिस्सा निकालता है और संरेखण अप्रासंगिक है, लेकिन मैं पहले से ही कैश्ड डेटा के बारे में बात कर रहा हूं)।
आर .. गिटहब स्टॉप हेल्पिंग ICE

@DarkDust: PS3 SPU पर पढ़े या लिखे बिना लिखे बाइट का समर्थन नहीं करता है। वास्तव में यह स्केलर प्रकारों का भी समर्थन नहीं करता है, केवल वेक्टर हैं, जिन्हें संरेखित किया जाना चाहिए। संकलक उनका अनुकरण करते हैं। और कई एआरएम प्रोसेसर बाइट पढ़ने या लिखने का समर्थन नहीं करते हैं, लेकिन केवल शब्द पढ़ने या लिखने का काम करते हैं।
सिल्वेन डेफ्रेसने
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.