2012-10-17 25 views
7

जोड़ना तो मैं char को char* में जोड़ने की कोशिश कर रहा हूं।सी चार से चार *

उदाहरण के लिए मुझे लगता है मैं भी char ch = 'x';

मैं append(word, ch); कर इस विधि का उपयोग ..

void append(char* s, char c) 
{ 

    int len = strlen(s); 
    s[len] = c; 
    s[len+1] = '\0'; 
} 

यह मुझे एक विभाजन गलती देता है char *word = " "; है, और मैं समझता हूँ कि क्यों मुझे लगता है। क्योंकि s[len] सीमा से बाहर है। मैं इसे कैसे बना सकता हूं ताकि यह काम करे? मुझे char* को भी बहुत कुछ साफ़ करने की आवश्यकता है, अगर मुझे चार शब्द [500] जैसे कुछ उपयोग करना था; मैं कैसे साफ़ करूंगा कि एक बार इसमें कुछ पात्र जोड़े जाएंगे? strlen हमेशा 500 होगा? अग्रिम में धन्यवाद।

+2

"क्योंकि एस [लेन] सीमा से बाहर है।" <- शुरुआत के लिए बहुत अच्छी तरह से देखा! बधाई। हालांकि, आपके पास अभी भी एक और त्रुटि है - एक स्ट्रिंग अक्षरशः पढ़ा जाता है, आप इसकी सामग्री को संशोधित नहीं कर सकते हैं। –

+2

@ एच 2CO3 '[लेन + 1] 'सीमा से बाहर है। 's [len]' शून्य बाइट है, जिसे 'strlen' द्वारा गिना जाता है। – pmr

+0

@pmr हाँ, तकनीकी रूप से सही। मुझे इसके बजाय 'sizeof (ओं) लिखा होगा। –

उत्तर

10

ठेठ सी अभ्यास होगा जैसे:

//returns 1 if failed, 0 if succeeded 
int append(char*s, size_t size, char c) { 
    if(strlen(s) + 1 >= size) { 
      return 1; 
    } 
    int len = strlen(s); 
    s[len] = c; 
    s[len+1] = '\0'; 
    return 0; 
} 

जब एक समारोह एक सरणी गुजर समारोह को संशोधित करने के संकलन समय यह कितनी जगह है में कोई विचार है। सी में सामान्य अभ्यास भी सरणी की लंबाई को पास करना है, और फ़ंक्शन इस बाध्यता पर भरोसा करेगा और विफल होगा यदि यह उस स्थान पर अपना काम नहीं कर सकता है। एक और विकल्प नई सरणी को पुन: आवंटित करने और वापस करने के लिए है, आपको char* वापस करने की आवश्यकता होगी या इनपुट के रूप में char** लेना होगा, लेकिन आपको इस स्थिति में ढेर स्मृति को प्रबंधित करने के तरीके के बारे में सावधानी से सोचना चाहिए। लेकिन पुन: आवंटित किए बिना, हां, आपके फ़ंक्शन को किसी भी तरह विफल होना चाहिए यदि इसे कोई स्थान छोड़ा जाने पर संलग्न करने के लिए कहा जाता है, तो यह आपके लिए असफल होने के लिए तैयार है।

char *append(const char *s, char c) { 
    int len = strlen(s); 
    char buf[len+2]; 
    strcpy(buf, s); 
    buf[len] = c; 
    buf[len + 1] = 0; 
    return strdup(buf); 
} 

लौटे स्ट्रिंग पुनःआवंटन जब यह साथ किया सुनिश्चित करें:

+0

यह बुरा जवाब है क्योंकि आप नहीं जानते कि * एस में स्ट्रिंग अक्षर हैं या नहीं। वे आमतौर पर केवल पढ़ने की स्मृति में संग्रहीत होते हैं और यदि आप उन्हें संशोधित करते हैं तो इसका उपयोग उल्लंघन हो सकता है। आपका कोड काम कर सकता है लेकिन इसे अपरिभाषित व्यवहार के रूप में माना जाता है। – user1888162

+0

@ user1888162 यदि आप आकार के लिए बड़ी संख्या में पास करते हैं तो यह भी यूबी है। – djechlin

3

आप,

append("foo", 'X'); 

यह दुर्घटना जाएगा में गुजर रहे हैं क्योंकि foo सामान्य रूप से केवल पढ़ने के लिए भंडारण में डाल दिया है। यहां तक ​​कि यदि यह नहीं है तो यह शायद कुछ खराब हो जाएगा! इस मामले में कंपाइलर अगर आपको दयालु है तो आपको कॉन्स्ट char * से char * में रूपांतरण की चेतावनी दी जानी चाहिए जो एक सुराग होगा।

5

यह सी में यथा-स्थान एक स्ट्रिंग में जोड़ने के लिए कुछ इस तरह की कोशिश करो कठिन है।

FYI: यह शायद segfaults क्योंकि आप जिस स्ट्रिंग को पारित कर रहे हैं उसे केवल पढ़ने योग्य स्मृति में संग्रहीत किया जाता है। लेकिन आप सही हैं, आप अंत से भी लिख रहे हैं ([len+1] लिखें, [len] एक नहीं)।

+0

चार बफ [लेन + 2] संकलित नहीं हो सकता है, उसके कंपाइलर के संस्करण के आधार पर –

0

हाँ, इस धारणा आपके द्वारा किए गए है - लगभग - सही - दुर्घटना हो सकता है क्योंकि आप अतीत स्ट्रिंग (वास्तव में केवल s[strlen(s) + 1], सीमा से बाहर है क्योंकि s[strlen(s)] अभी भी एक मान्य स्थान है की सीमा से लिखने की कोशिश कर रहे हैं - समापन एनयूएल बाइट वहां संग्रहित है)। लेकिन आप एक स्ट्रिंग अक्षर को भी संशोधित नहीं कर सकते हैं, क्योंकि यह आमतौर पर प्रक्रिया मेमोरी के कुछ पाठक भाग में होता है। इन दोनों कार्यों में अपरिभाषित व्यवहार का आह्वान होता है, जिसमें दुर्घटनाग्रस्त होने की संभावना होती है। आप स्ट्रिंग को डायनामिक रूप से आवंटित स्टोरेज में प्रतिलिपि बनाकर प्रतिलिपि बनाकर इस समस्या को हल कर सकते हैं। साथ ही, आपको अपने कार्य के तर्क में const char * का उपयोग करना होगा, क्योंकि char * बताता है कि केवल-पढ़ने वाले तारों को पारित नहीं किया जा सकता है।जब यह अब कोई आवश्यकता नहीं है

char *append(const char *orig, char c) 
{ 
    size_t sz = strlen(orig); 
    char *str = malloc(sz + 2); 
    strcpy(str, orig); 
    str[sz] = c; 
    str[sz + 1] = '\0'; 
    return str; 
} 

इसके अलावा, लौटे स्ट्रिंग free() को भूल नहीं है।

0

आप वास्तव में सुरक्षित रूप से एक मनमानी स्ट्रिंग में शामिल नहीं हो सकते हैं, क्योंकि सबसे पहले, स्ट्रिंग स्थिरांक केवल पढ़ने योग्य स्मृति में होते हैं, इसलिए उन्हें लिखने की कोशिश करने से एक सेगमेंटेशन गलती हो सकती है, और दूसरी बात, आपके पास कोई गारंटी नहीं है कि अगर उन्होंने आपको एक बफर पास कर दिया है जिसे आपने इसके अंत में नहीं गोली मार दी है।

विशेष रूप से, यदि आप char x [500] करते हैं;

कोई गारंटी नहीं है कि strlen (x) आपको 500 वापस कर देगा। यह आपको वापस लौटाएगा इससे पहले कि यह शून्य की शुरुआत से आगे बढ़ने के लिए कितने पात्रों को गिनती हो। यह आपको 0, 1 ... 500, 501 ..., x में क्या है के आधार पर वापस कर सकता है।

वास्तव में आपके केवल एक ही विकल्प को बफर के आकार के साथ जोड़ना है जिसे आप जोड़ रहे हैं (ताकि आप बफर भरने पर कुछ उचित कर सकें), या प्रत्येक बार इसे बुलाए जाने पर एक नया बफर आवंटित करने के लिए, इस मामले में आपको बफर को फिर से मुक्त करने की आवश्यकता होगी।

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