2012-05-27 10 views
5

मुझे यहाँ क्या याद आ रही है? यह मुझे पागल कर रहा है!सी ++: मैं स्पिंटफ के साथ एक कॉन्स चार * क्यों मुद्रित नहीं कर सकता?

..... 
..... 
char str[50];  
sprintf(str, "%s", Notation()); 
..... 
..... 

लेकिन str अपरिवर्तित रहता है:

मैं एक समारोह है कि कोड के दूसरे हिस्से में एक स्थिरांक चार *

const char* Notation() const 
{ 
    char s[10]; 
    int x=5; 
    sprintf(s, "%d", x); 
    return s; 
} 

रिटर्न अब मैं यह कर रहा हूं की है।

, तो इसके बजाय मैं यह कर:

..... 
..... 
char str[50]; 
str[0]=0; 
strcat(str, Notation()); 
..... 
..... 

str ठीक से सेट है।

मैं क्यों sprintf अपेक्षा के अनुरूप काम नहीं कर रहा है सोच रहा हूँ ...

+0

शायद एक विचार फ़ंक्शन को बदलने के लिए है: शून्य नोटेशन (char * buffer) const और कॉलर द्वारा प्रदत्त चार बफर पर काम करें। – Wartin

+0

डाउनवोट क्यों? सवाल स्पष्ट है, एक "कामकाजी" नमूना दिया गया था, जो प्रयास दिखाता है, और वास्तविक समस्या नमूना दिया जाता है। – chris

उत्तर

9

आप एक सरणी ढेर पर आवंटित वापस जाने के लिए कोशिश कर रहे हैं और अपने व्यवहार अनिर्धारित रहता है।

const char* Notation() const 
{ 
    char s[10]; 
    int x=5; 
    sprintf(s, "%d", x); 
    return s; 
} 

यहाँ s के आसपास होने के लिए के बाद आप समारोह Notation() से लौटा दिया नहीं जा रहा है। यदि आप थ्रेड सुरक्षा से चिंतित नहीं हैं तो आप s स्थिर बना सकते हैं।

const char* Notation() const 
{ 
    static char s[10]; 
    .... 
+0

मैंने सोचा कि बफर संकलन समय पर आवंटित किया गया है और आवेदन के जीवनकाल के लिए वहां रहता है। यदि यह सत्य नहीं है, तो इसका मतलब यह नहीं होगा कि गैर-वैश्विक कॉन्स char * लौटने वाला प्रत्येक कार्य गलत है? (और खतरनाक) – Wartin

+1

कोई भी फ़ंक्शन जो स्वचालित कॉन्स char * देता है वह खतरनाक है। बफर लौटने के कई अन्य तरीके हैं - उदाहरण के लिए मॉलोक का उपयोग करके स्थैतिक और नए आवंटित बफर। हालांकि यदि आप malloc'd buffers को वापस करते हैं तो आपको क्लीनअप को ठीक से प्रबंधित करना होगा। – hawk

+0

@ वार्टिन: मुझे लगता है कि आप स्ट्रिंग अक्षर के बारे में सोच रहे हैं। यदि, उदाहरण के लिए, आपने कहा: 'वापसी "foobar"; '- यह सुरक्षित होगा, क्योंकि स्ट्रिंग" foobar "आवेदन के जीवनकाल के माध्यम से रहता है। –

5

दोनों मामलों में, यह अनिर्धारित व्यवहार का आह्वान, के रूप में Notation() एक स्थानीय सरणी जो लौटने पर नष्ट कर दिया जाता है देता है। आप दुर्भाग्यपूर्ण हैं कि यह एक मामले में काम करता है, जिससे आपको लगता है कि यह सही है।

std::string Notation() const 
{ 
    int x=5; 
    std::ostringstream oss; 
    oss << x; 
    return oss.str(); 
} 

और उसके बाद:

char str[50];  
sprintf(str, "%s", Notation().c_str()); 

लाभ (और सौंदर्य) std::ostringstream की

std::string Notation() const 
{ 
    char s[10]; 
    int x=5; 
    sprintf(s, "%d", x); 
    return s; //it is okay now, s gets converted into std::string 
} 

या सी का उपयोग कर ++ के रूप में धारा:

समाधान के रूप में std::string उपयोग करने के लिए है (और std::string) यह है कि आपको आउटपुट के आकार को जानने की ज़रूरत नहीं है I एन अग्रिम, जिसका अर्थ है कि आपको 10 जैसे कि char s[10] में जादू संख्या का उपयोग करने की आवश्यकता नहीं है। ये वर्ग उस अर्थ में सुरक्षित हैं।

1

Notation में स्टैक पर रखा गया है, इसलिए यह Notation फ़ंक्शन से बाहर निकलने के बाद नष्ट हो जाता है। इस तरह के चर automatic कहा जाता है।आप new का उपयोग कर ढेर में अपने स्ट्रिंग को बचाने की जरूरत:

char *s = new char[10]; 

लेकिन आप मैन्युअल रूप से इस स्मृति मुक्त करने के लिए है:

char str[50]; 
const char *nt = Notation(); 
sprintf(str, "%s", nt); 
printf("%s", str); 
delete[] nt; 

तुम सच में सी का उपयोग करते हैं ++ तो का उपयोग में निर्मित string वर्ग Nawaz तरह का सुझाव दिया। यदि आप किसी भी तरह कच्चे पॉइंटर्स तक सीमित हैं तो Notation के बाहर बफर आवंटित करें और इसे destanation पैरामीटर जैसे sprintf या strcat पर पास करें।

+1

जैसे स्मार्ट पॉइंटर का उपयोग करें, जबकि इससे समस्या हल हो जाएगी, यह एक भयानक विचार है। अगर उसने फ़ंक्शन का उपयोग करने की कोशिश की जिस तरह से वह अब है, तो यह एक गारंटीकृत स्मृति रिसाव होगी। –

+0

हां, यही वह है। चूंकि प्रश्न सी ++ के बारे में है, तो 'स्ट्रिंग' सबसे अच्छा विकल्प है। – Kirill

संबंधित मुद्दे