सी

2010-02-26 2 views
10

में एक स्ट्रिंग को रिवर्स करना मुझे पता है कि यह हजारों बार पूछा गया है लेकिन मुझे बस मेरे कोड में त्रुटि नहीं मिल रही है। क्या कोई कृपया बता सकता है कि मैं क्या गलत कर रहा हूं?सी

#include <stdlib.h> 
#include <string.h> 

void reverseString(char *myString){ 
    char temp; 
    int len = strlen(myString); 

    char *left = myString; 
    // char *right = &myString[len-1];                       
    char *right = myString + strlen(myString) - 1; 

    while(left < right){ 
    temp = *left; 
    *left = *right; // this line seems to be causing a segfault                
    *right = temp; 
    left++; 
    right--; 
    } 
} 

int main(void){ 
    char *somestring = "hello"; 
    printf("%s\n", somestring); 
    reverseString(somestring); 

    printf("%s", somestring); 

} 
+1

भले ही आपके सवाल का जवाब लोगों को यह लगा बाहर है, तो आप कभी नहीं कहा कि क्या त्रुटि आप मिल रहे थे, या क्या काम नहीं कर रहा था! आपको हमेशा जो भी उम्मीद है, और जो आपने वास्तव में देखा है उसका वर्णन करना चाहिए। (गलत आउटपुट? Seg-fault/GPF त्रुटि? अनंत लूप/लटका?) – abelenky

+0

यह एक segfault था। मुझे इसका उल्लेख करना चाहिए था, अनुस्मारक के लिए धन्यवाद। – qwer

उत्तर

13

समस्या यहाँ

char *somestring = "hello"; 

somestring स्ट्रिंग शाब्दिक "हैलो" को अंक है। सी ++ मानक यह गारंटी नहीं देता है, लेकिन अधिकांश मशीनों पर, यह केवल-पढ़ने वाला डेटा होगा, इसलिए आपको इसे संशोधित करने की अनुमति नहीं दी जाएगी।

इसे इस तरह की घोषणा के बजाय

char somestring[] = "hello"; 
+0

जो चीज़ मैं इस दृष्टिकोण के बारे में नापसंद करता हूं वह यह है कि फ़ंक्शन इसके इनपुट पैरामीटर को संशोधित करेगा। YMMV। – dirkgently

+1

dirkgently: हाँ, लेकिन यह विकल्प के रूप में लगभग दोगुनी तेजी से और कम स्मृति का उपयोग करता है। कुछ प्रोग्रामर उन कार्यों पर काम करते हैं जहां प्रदर्शन महत्वपूर्ण है। –

+3

यदि आपके एप्लिकेशन का प्रदर्शन महत्वपूर्ण भाग एक तंग लूप में तारों को उलट रहा है, तो मुझे लगता है कि आपको अपने डिज़ाइन पर पुनर्विचार करना चाहिए। –

6

आप एक संभावित केवल पढ़ने के लिए स्मृति क्षेत्र को संशोधित करने की कोशिश कर रहा द्वारा अपरिभाषित व्यवहार लागू कर रहे हैं (स्ट्रिंग शाब्दिक परोक्ष const कर रहे हैं - यह उन्हें पढ़ने के लिए ठीक है, लेकिन उन्हें लिखने के लिए नहीं)। एक नई स्ट्रिंग बनाएं और इसे वापस करें, या एक बड़ा पर्याप्त बफर पास करें और इसके लिए उलटा स्ट्रिंग लिखें।

-1

अपने तर्क सही लगता है। पॉइंटर्स का उपयोग करने के बजाय, char[] से निपटने के लिए क्लीनर है।

13

अंततः, यह स्थान में उल्टा करने के लिए है, तो जैसे क्लीनर होगा:

#include <stdio.h> 
#include <string.h> 

void 
reverse(char *s) 
{ 
    int a, b, c; 
    for (b = 0, c = strlen(s) - 1; b < c; b++, c--) { 
     a = s[b]; 
     s[b] = s[c]; 
     s[c] = a; 
    } 

    return; 
} 

int main(void) 
{ 
    char string[] = "hello"; 
    printf("%s\n", string); 
    reverse(string); 
    printf("%s\n", string); 

    return 0; 
} 

आपका समाधान अनिवार्य रूप से इस एक का एक अर्थ की दृष्टि से बड़ा संस्करण है। एक सूचक और एक सरणी के बीच अंतर को समझें। मानक स्पष्ट रूप से बताता है कि इस तरह के एक ऑपरेशन का व्यवहार (एक स्ट्रिंग अक्षर की सामग्री का संशोधन) अनिर्धारित है। तुम भी एस्किमो से this अंश देखना चाहिए:

आप एक स्ट्रिंग निरंतर के साथ एक चरित्र सरणी को प्रारंभ करते समय:

char string[] = "Hello, world!"; 

आप एक सरणी स्ट्रिंग वाली के साथ खत्म हो, और आप के लिए सरणी की सामग्री को संशोधित कर सकते हैं अपने दिल की सामग्री:

string[0] = 'J'; 

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

char *p1 = "Hello"; 
int len = strlen("world"); 

यह लगभग रूप में अगर आप ने कहा था है

char internal_string_1[] = "Hello"; 
char internal_string_2[] = "world"; 
char *p1 = &internal_string_1[0]; 
int len = strlen(&internal_string_2[0]); 

यहाँ, सरणियों internal_string_1 नामित और internal_string_2 तथ्य यह है कि संकलक वास्तव में थोड़ा अस्थायी पैदा कर रहा है का सुझाव करने वाले हैं प्रत्येक बार जब आप अपने कोड में एक स्ट्रिंग स्थिर का उपयोग करते हैं तो सरणी। हालांकि, सूक्ष्म तथ्य यह है कि स्ट्रिंग स्थिरांक के पीछे वाले सरणी आवश्यक रूप से संशोधित नहीं हैं। विशेष रूप से, कंपाइलर उन्हें केवल-पढ़ने-मेमोरी में संग्रहीत कर सकता है। इसलिए, यदि आप लिखना

char *p3 = "Hello, world!"; 
p3[0] = 'J'; 

अपने कार्यक्रम, क्रैश हो सकता है, क्योंकि यह एक मूल्य के स्टोर करने के लिए कोशिश कर सकते हैं (इस मामले में, चरित्र 'जे') nonwritable स्मृति में।

नैतिक यह है कि जब भी आप तारों का निर्माण या संशोधन कर रहे हों, तो आपको यह सुनिश्चित करना होगा कि आप जो मेमोरी बना रहे हैं या उन्हें संशोधित कर रहे हैं वह लिखने योग्य है।वह स्मृति या तो आपके द्वारा आवंटित एक सरणी होनी चाहिए, या कुछ स्मृति जो आपने गतिशील रूप से उन तकनीकों द्वारा आवंटित की हैं जिन्हें हम अगले अध्याय में देखेंगे। सुनिश्चित करें कि आपके प्रोग्राम का कोई भी हिस्सा कभी भी एक स्ट्रिंग को संशोधित करने का प्रयास नहीं करेगा जो वास्तव में अज्ञात, अवांछित सरणी में से एक है जो आपके स्ट्रिंग स्थिरांक में से एक के जवाब में आपके लिए जेनरेट किया गया संकलक है। (एकमात्र अपवाद सरणी प्रारंभिकता है, क्योंकि यदि आप इस तरह के सरणी को लिखते हैं, तो आप सरणी को लिख रहे हैं, स्ट्रिंग अक्षर के लिए नहीं जिसे आपने सरणी को प्रारंभ करने के लिए उपयोग किया था।) "

+1

कोड और स्पष्टीकरण के लिए लिंक के लिए धन्यवाद! मैंने इस अनुभव से बहुत कुछ सीखा है, मैं कल्पना करने की परवाह करता हूं: पी – qwer

+0

@qwer: मदद करने में खुशी हुई। –

+1

किकस उत्तर। –

0

आप निम्न कोड का उपयोग कर सकते हैं

#include<stdio.h> 
#include<string.h> 
#include<malloc.h> 
char * reverse(char*); 

int main() 
{ 
     char* string = "hello"; 
     printf("The reverse string is : %s", reverse(string)); 
     return 0; 
} 

char * reverse(char* string) 
{ 

    int var=strlen(string)-1; 
    int i,k; 
    char *array; 
    array=malloc(100); 
    for(i=var,k=0;i>=0;i--) 
    { 
      array[k]=string[i]; 
      k++; 
    } 
    return array; 
} 
0

मैं ले यह strrev (बुला) सवाल से बाहर है?

+0

हां, बिंदु खुद को लिखने का प्रयास करना था। – qwer