2012-02-15 16 views
6
include<stdio.h> 
int main() 
{ 
    //char b[10]; 
    char *a="goodone"; 
    //a=b; 

    scanf("%s",a);//this scanf fails and thow segmentation fault. 
    printf("%s",a); 

} 

यह क्यों काम नहीं कर रहा है? मैंने इस स्कैनफ के साथ बहुत कोशिश की लेकिन, जब मैं अपने चर के लिए स्मृति आरक्षित करता हूं * (एक = बी (टिप्पणी) असाइन करके) यह ठीक काम करता है। अन्यथा यह नहीं है। मेरा मानना ​​है कि char * a अपनी स्ट्रिंग के लिए कुछ मेमोरी आवंटित करेगा, ("अच्छा") और उस मेमोरी लोकेशन को उसके मान पर वापस कर देगा। और printf इस विश्वास के साथ ठीक काम क्यों स्कैन नहीं? कृपया मुझे इस से बचाने ....एक स्ट्रिंग अक्षर पर लिखते समय स्कैनफ़ अपेक्षित रूप से क्यों काम नहीं कर रहा है?

+0

मैं इस प्रश्न के लिए [सी एफएक्यू एंट्री] (http://c-faq.com/aryptr/aryptr2.html) पढ़ने की दृढ़ता से अनुशंसा करता हूं। – Lundin

+0

यह निश्चित रूप से एक अच्छा पठन है: [char \ \ \] = "string" के बीच क्या अंतर है; और char * p = "string";] (http://stackoverflow.com/questions/9460260/what-is-the-difference-between-char-a-string-and-char-p-string) –

उत्तर

2

इसका कारण यह है कि आप scanf निर्देश देते रहे हैं डेटा है कि यह स्मृति const char* मूल्य के लिए आवंटित है, यानी केवल पढ़ने के लिए स्मृति में में पढ़ता लिखने के लिए।

आप अपने स्ट्रिंग निरंतर लिखने योग्य बनाने के लिए, बदलने

char *a="goodone"; 

को

char a[]="goodone"; 

ध्यान दें कि यह सुरक्षित भी नहीं है करना चाहते हैं: जब उपयोगकर्ता एक से अधिक सात वर्ण में प्रवेश करती है यह क्रैश हो सकता है । उस समस्या को हल करने के लिए अपने प्रारूप विनिर्देशक की सीमा जोड़ें:

scanf("%7s",a); 

पीएस टिप्पणी की गई a=b ठीक काम करता है क्योंकि यह स्ट्रिंग निरंतर संशोधित नहीं कर रहा है; बल्कि, यह पॉइंटर को चरित्र निरंतर संशोधित करता है, जो अनुमत है।

+2

जोर देने के लिए बिंदु, * कभी भी 'baref()' का उपयोग नंगे '% s' प्रारूप के साथ करें। इससे कोई फर्क नहीं पड़ता कि आप कितने बड़े बफर प्रदान करते हैं, आप उपयोगकर्ता को पर्याप्त वर्णों में प्रवेश करने से रोक नहीं सकते हैं। यह असुरक्षित है क्योंकि 'get() '(जिसे कभी भी उपयोग नहीं किया जाना चाहिए)। –

+0

@ किथ थॉम्पसन हो जाता है() सी 11 के बाद से मानक सी नहीं है। – Lundin

+0

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

1

char *achar पर सिर्फ एक सूचक है। जब आप "goodone" को असाइन करते हैं, तो यह उस स्ट्रिंग शाब्दिक (जो केवल पढ़ने के लिए) को इंगित करता है, और scanf उस स्ट्रिंग को उस स्मृति में ओवरराइट करने का प्रयास करता है जो क्रैश का कारण बनता है।

आप इसे करने के b असाइन करते हैं, तो आप 10 char रों की एक लिखने योग्य स्मृति क्षेत्र को a की ओर इशारा करते है (अर्थात, अधिकतम लंबाई के एक स्ट्रिंग 9 + समाप्त NUL)। तो यह तब तक काम करता है जब तक scanf उसमें से अधिक कुछ भी संग्रहीत नहीं कर रहा है।

इसी प्रकार आप सूचक के बजाय a एक सरणी बना सकते हैं (यानी char a[] = "goodone";)। फिर आपको वहां देखने की ज़रूरत है कि वहां कुछ और स्टोर न करें।

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