2012-03-27 11 views
15

मैं सी में एक स्ट्रिंग से एक चरित्र को हटाने का प्रयास कर रहा हूं। मेरे कोड के साथ समस्या यह है कि यह स्ट्रिंग से वर्ण के पहले उदाहरण को हटा देता है लेकिन स्ट्रिंग में उस चरित्र के बाद भी सबकुछ मिटा देता है। उदाहरण के लिए, को दूर करने 'हैलो' प्रिंट 'वह' से 'एल' के बजाय 'Heo'सी में स्ट्रिंग से दिए गए वर्ण की सभी घटनाओं को कैसे हटाएं?

int i; 
char str1[30] = "Hello", *ptr1, c = 'l'; 
ptr1 = str1; 
for (i=0; i<strlen(str1); i++) 
{ 
    if (*ptr1 == c) *ptr1 = 0; 
    printf("%c\n", *ptr1); 
    ptr1++; 
} 

मैं इस के लिए संकेत का उपयोग करने की आवश्यकता है और यह संभव के रूप में सरल रखने के लिए के बाद से मैं अभी शुरुआत कर रहा हूँ चाहते हैं की तुलना में सी में धन्यवाद

+1

संकेत: हटाने के दौरान, आप हटाए गए लोगों को कवर करने के लिए अन्य अक्षरों को स्थानांतरित करना चाहते हैं। '* ptr1 = 0; 'ऐसा करने का तरीका नहीं है। –

+0

आप प्रत्येक char की अनुक्रमणिका को संबोधित करने के लिए एक/लूप का भी उपयोग कर रहे हैं, लेकिन आप कभी भी वास्तविक सूचकांक (i का मान) –

+0

याद रखने की एक और बात नहीं है, सीएस में, तारों को निरस्त कर दिया गया है। –

उत्तर

20

आप इस तरह यह कर सकते हैं:

void remove_all_chars(char* str, char c) { 
    char *pr = str, *pw = str; 
    while (*pr) { 
     *pw = *pr++; 
     pw += (*pw != c); 
    } 
    *pw = '\0'; 
} 

int main() { 
    char str[] = "llHello, world!ll"; 
    remove_all_chars(str, 'l'); 
    printf("'%s'\n", str); 
    return 0; 
} 

विचार एक अलग पढ़ने रखने के लिए और संकेत (पढ़ने के लिए pr और pw लेखन के लिए) लिखते हैं, हमेशा पढ़ने सूचक अग्रिम, और लेखन सूचक अग्रिम है केवल तभी जब यह किसी दिए गए चरित्र को इंगित नहीं कर रहा हो।

+0

सरल उत्तर और विवरण के लिए धन्यवाद, जिसने इसे हल किया। हर किसी के इनपुट के लिए भी धन्यवाद। – boutrosc

+0

क्यों http://melpon.org/wandbox/permlink/qZPdItEH7hjg4sl3 विभाजन खंड में परिणाम? '* Pw = * ptr ++;' और '* pw = (* ptr) ++;' – Destructor

+0

@Destructor '* pw = * ptr ++' पॉइंटर (सही) में वृद्धि करता है, जबकि '(* ptr) ++' चरित्र (गलत) बढ़ाता है। – dasblinkenlight

-1

सी के रूप में एक स्ट्रिंग को परिभाषित करता है "पात्रों में से एक सन्निहित अनुक्रम द्वारा समाप्त और पहली अशक्त चरित्र सहित"

+1

सही है, लेकिन शायद ही सवाल का एक व्याख्यात्मक उत्तर है। –

0

बस बदलने

if (*ptr1 == c) *ptr1 = 0; 

if (*ptr1 == c) continue; 

रूप @ouah ने कहा, यह पहली बार शून्य चरित्र पर टूट जाता है के लिए

..

+0

यह पर्याप्त फिक्स नहीं है। –

1

समस्या यह है कि जब आप पहली बार चरित्र कि c से मेल खाता सामना करते हैं, आप एक अशक्त चरित्र सम्मिलित है ठीक वहीं। इसका मतलब है कि आप अनिवार्य रूप से बाकी स्ट्रिंग को काट रहे हैं।

आपको मिलान करने वाले चरित्र को खोजने के दौरान आपको क्या करना है, निम्न वर्णों को एक स्थिति में वापस ले जाएं। फिर आपको कितने अक्षर हटा दिए गए हैं इस पर निर्भर करते हुए आपको अंत में शून्य वर्ण डालने की आवश्यकता है।

2
char str1[30] = "Hello", *prt1, c = 'l'; 
char str2[30], *prt2; 
prt1 = str1; 
prt2 = str2; 
while(*prt1 != 0) 
{ 
    if(*prt1 != c) 
    { 
     *prt2 = *prt1; 
     prt2++; 
    } 
    prt1++; 
} 
*prt2 = '\0'; 
4

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

int i; 
char str1[30] = "Hello", *ptr1, c = 'l'; 
char str2[30] = {0}, *ptr2; 
ptr1 = str1; 
ptr2 = str2; 
for (i=0; i<strlen(str1); i++) 
{ 
    if (*ptr1 != c) *ptr2++=*ptr1; 
    ptr1++; 
} 
printf("%s\n", str2); 
+1

सिवाय इसके कि आपको वास्तव में ऐसे लूप की स्थिति में 'strlen()' को कॉल नहीं करना चाहिए, यह एक अच्छा जवाब है। अनुमोदित, यह प्रश्न में कोड से विरासत में मिली गलती है, लेकिन ... –

+0

@ जोनाथन लेफ्लर, यह उत्तर कुछ मौलिक त्रुटियों को बनाता है जो इसे एक अच्छे उत्तर से रोकते हैं। जब भी कोई चरित्र हटा दिया जाता है तो आपको स्ट्रिंग के अवशेषों को बाईं ओर बाईं ओर स्थानांतरित करने की आवश्यकता नहीं होती है। यह एक नेस्टेड लूप का अर्थ होगा, जो उत्तर दिखाता है, आवश्यक नहीं है। साथ ही, क्या आप चरित्र को एक स्ट्रिंग से दूसरी स्ट्रिंग में कॉपी करते हैं, इससे कोई फर्क नहीं पड़ता है, क्योंकि यह रैम का एक ही ब्लॉक है। वास्तव में, यह शायद दूसरी स्ट्रिंग का उपयोग करने में अधिक अक्षम है, क्योंकि आप स्मृति के दूरस्थ ब्लॉक का उपयोग कर कैश मिस को जोखिम देते हैं। –

1

मुझे पता है कि यह एक प्रकार का डुप्लिकेट उत्तर है, लेकिन यह कोड समस्या को हल करने के लिए कार्य का संस्करण है। मैंने सोचा कि जैसा कि प्रश्नकर्ता एक नौसिखिया था, वह समस्या के विघटित संस्करण से बहुत कुछ सीख सकता है।

int del_x_char(char *p, int x) 
{ 
    char *q; 
    x=first_occurance(p, 'i')/*you can replace any character that you want delete with 'i'*/ 
    q=p+x; 
    while(*q=*(q+1)) 
     q++; 
    *q='\0'; 
    return 0; 
} 
int first_occurance(char *q, char phar) 
{ 
    int i=0; 
    while(*q) 
    { 
     if(*q++==phar) 
      return i; 
     i++; 
    } 
    return -1; 
} 
संबंधित मुद्दे