दिलचस्प पोस्ट
सी – कमांड लाइन पैरामीटर पढ़ना DOMContentLoaded और लोड घटनाओं के बीच का अंतर आईआईएस एक्सप्रेस वेब सर्वर को लॉन्च करने में असमर्थ सबसे कुशल जावा संग्रह लाइब्रेरी क्या है? डोम प्रसंस्करण के बाद एक्सएमएल गुणों का क्रम मेरे उपकरणबॉक्स में कौन सी आधुनिक सी ++ लाइब्रेरी होनी चाहिए? चेनिंग कोर एनिमेशन एनिमेशन $। एजेक्स ({async: false}) अनुरोध अभी भी एसिंक्रोनस को फ़ायरिंग कर रहा है? एस 3 में डेटा कैसे स्टोर करें और रेल एपीआई / आईओएस ग्राहक के साथ एक सुरक्षित तरीके से उपयोगकर्ता पहुंच की अनुमति दें? MongoDB – सॉकेट के लिए अनुमति अस्वीकृत: /tmp/mongodb-27017.sock IOS पर CommonCrypto का उपयोग करके पीबीकेडीएफ 2 PHP में फ़ाइल करने के लिए एक नई पंक्ति लेखन .NET का उपयोग करना, आप फ़ाइल हस्ताक्षर के आधार पर फ़ाइल का माइम प्रकार कैसे प्राप्त कर सकते हैं, विस्तार नहीं आईओएस एप के भीतर से बारकोड जेनरेशन वेतन वृद्धि int वस्तु

सी में एक स्ट्रिंग उल्टा

मैंने एक रिवर्स स्ट्रिंग प्रोग्राम विकसित किया है। मैं सोच रहा हूं कि ऐसा करने का एक बेहतर तरीका है, और अगर मेरे कोड में कोई संभावित समस्याएं हैं मैं सी के कुछ उन्नत सुविधाओं का अभ्यास करने के लिए देख रहा हूं।

char* reverse_string(char *str) { char temp; size_t len = strlen(str) - 1; size_t i; size_t k = len; for(i = 0; i < len; i++) { temp = str[k]; str[k] = str[i]; str[i] = temp; k--; /* As 2 characters are changing place for each cycle of the loop only traverse half the array of characters */ if(k == (len / 2)) { break; } } } 

Solutions Collecting From Web of "सी में एक स्ट्रिंग उल्टा"

यदि आप सी की उन्नत सुविधाओं का अभ्यास करना चाहते हैं, तो पॉइंटर्स के बारे में कैसे? मैक्रो और एक्सएर-स्वैप में भी मस्ती के लिए टॉस कर सकते हैं!

 #include <string.h> // for strlen() // reverse the given null-terminated string in place void inplace_reverse(char * str) { if (str) { char * end = str + strlen(str) - 1; // swap the values in the two given variables // XXX: fails when a and b refer to same memory location # define XOR_SWAP(a,b) do\ {\ a ^= b;\ b ^= a;\ a ^= b;\ } while (0) // walk inwards from both ends of the string, // swapping until we get to the middle while (str < end) { XOR_SWAP(*str, *end); str++; end--; } # undef XOR_SWAP } } 

एक संकेतक (जैसे char * , पॉइंटर से char * तक दाएं से बाएं पढ़ता है) सी में एक डेटा प्रकार होता है जिसका उपयोग किसी अन्य मान की स्मृति में स्थान को संदर्भित करने के लिए किया जाता है। इस स्थिति में, स्थान जहां एक char संग्रहीत होता है। हम एक * साथ prefixing द्वारा dereference पॉइंटर्स कर सकते हैं, जो हमें उस स्थान पर संग्रहीत मान देता है। तो str पर संग्रहीत मान *str

हम संकेतक के साथ सरल अंकगणित कर सकते हैं। जब हम एक संकेतक को बढ़ाते हैं (या घटाते हैं), तो हम उस प्रकार के मूल्य के लिए अगले (या पिछले) स्मृति स्थान को संदर्भित करने के लिए इसे स्थानांतरित करते हैं। विभिन्न प्रकार के संकेतकों को बढ़ाना पॉइंटर को एक अलग संख्या में बाइट्स में ले जाया जा सकता है क्योंकि सी में विभिन्न मानों के अलग-अलग आकार हैं।

यहां, हम स्ट्रिंग ( str ) के पहले unprocessed char को संदर्भित करने के लिए एक और दूसरे को अंतिम ( end ) का संदर्भ देने के लिए एक सूचक का उपयोग करते हैं। हम अपने मूल्यों ( *str और *end ) को स्वैप करते हैं, और संकेतक को स्ट्रिंग के बीच में ले जाते हैं। एक बार str >= end , या तो वे दोनों एक ही char को इंगित करते हैं, जिसका अर्थ है कि हमारे मूल स्ट्रिंग में एक अजीब लंबाई थी (और मध्य char को उलट करने की आवश्यकता नहीं है), या हमने सब कुछ संसाधित किया है

गमागमन करने के लिए, मैंने मैक्रो को परिभाषित किया है मैक्रोज़ C प्रीप्रोसेसर द्वारा किया गया टेक्स्ट प्रतिस्थापन है। वे कार्य से बहुत अलग हैं, और अंतर जानने में महत्वपूर्ण है। जब आप किसी फ़ंक्शन को कॉल करते हैं, तो फ़ंक्शन आपके द्वारा दिए गए मानों की एक प्रति पर कार्य करता है। जब आप मैक्रो कॉल करते हैं, तो यह केवल एक शाब्दिक प्रतिस्थापन करता है – इसलिए आपके द्वारा दिए गए तर्क सीधे उपयोग किए जाते हैं।

चूंकि मैंने केवल एक बार XOR_SWAP मैक्रो का उपयोग किया था, यह संभवतः इसे परिभाषित करने के लिए अतिरेक था, लेकिन यह अधिक स्पष्ट हुआ कि मैं क्या कर रहा था। सी प्रीप्रोसेसर मैक्रो का विस्तार करने के बाद, जबकि लूप इस तरह दिखता है:

  while (str < end) { do { *str ^= *end; *end ^= *str; *str ^= *end; } while (0); str++; end--; } 

ध्यान दें कि मैक्रो तर्क प्रत्येक बार मैक्रो परिभाषा में उपयोग किए जाने के लिए दिखाए जाते हैं यह बहुत उपयोगी हो सकता है – लेकिन गलत तरीके से उपयोग किए जाने पर भी आपका कोड तोड़ सकता है उदाहरण के लिए, यदि मैंने वेतन वृद्धि / घटते निर्देशों और मैक्रो कॉल को एक पंक्ति में संकुचित किया था, जैसे

  XOR_SWAP(*str++, *end--); 

तब यह विस्तार होगा

  do { *str++ ^= *end--; *end-- ^= *str++; *str++ ^= *end--; } while (0); 

जिसने वेतन वृद्धि / घटती कार्रवाई ट्रिपल कर दी है, और वास्तव में ऐसा स्वैप नहीं करता जो इसे करना चाहिए।

जब भी हम इस विषय पर हैं, आपको पता होना चाहिए कि एक्सर ( ^ ) का मतलब क्या है। यह एक बुनियादी अंकगणितीय संचालन है – जैसे अतिरिक्त, घटाव, गुणन, विभाजन, सिवाय इसके कि वह प्राथमिक स्कूल में आमतौर पर नहीं पढ़ाया जाता है। यह दो पूर्णांक बिट को बिट से जोड़ता है – जैसे अतिरिक्त, लेकिन हमें लेयर-ओवरों की परवाह नहीं है 1^1 = 0 , 1^0 = 1 , 0^1 = 1 , 0^0 = 0

दो मूल्यों को स्वैप करने के लिए एक अच्छी तरह से ज्ञात चाल एक्सरे का उपयोग करना है यह x और y सभी बुनियादी गुणों के कारण कार्य करता है: x ^ 0 = x , x ^ x = 0 और x ^ y = y ^ x तो कहें कि हमारे पास दो वैरिएबल a और b जो कि शुरू में दो मानों को v a और v b संग्रहीत करते हैं।

   // प्रारंभ में:
   // a == v a
   // बी == वी बी
   एक ^ = बी;
   // अब: ए == वी एक ^ वी बी
   बी ^ = ए;
   // अब: b == v b ^ (v एक ^ v b )
   // == v a ^ (v b ^ v b )
   // == वी एक ^ 0
   // == वी 
   एक ^ = बी;
   // अब: a == (v एक ^ v b ) ^ v a
   // == (v एक ^ v a ) ^ v b
   // == 0 ^ वी बी
   // == वी बी

इसलिए मूल्य बदले गए हैं इसमें एक बग है – जब a और b समान वैरिएबल हैं:

   // प्रारंभ में:
   // a == v a
   एक ^ = ए;
   // अब: ए == वी एक ^ वी एक
   // == 0
   एक ^ = ए;
   // अब: ए == 0 ^ 0
   // == 0
   एक ^ = ए;
   // अब: ए == 0 ^ 0
   // == 0

चूंकि हम str < end , यह कभी ऊपर के कोड में नहीं होता है, इसलिए हम ठीक हैं।

जबकि हम शुद्धता के बारे में चिंतित हैं, हमें अपने किनारे मामलों की जांच करनी चाहिए। if (str) पंक्ति को सुनिश्चित करना चाहिए कि हमें स्ट्रिंग के लिए एक NULL पॉइंटर नहीं दिया गया था। खाली स्ट्रिंग के बारे में क्या? अच्छी तरह से strlen("") == 0 , तो हम str - 1 रूप में end प्रारंभ करेंगे, जिसका अर्थ है कि while (str < end) स्थिति कभी भी सच नहीं है, इसलिए हम कुछ भी नहीं करते हैं। क्या सही है।

तलाशने के लिए सी का एक गुच्छा है इसके साथ मजे करो!

अद्यतन: एमएमवी एक अच्छा मुद्दा लाता है, जिसे आपको थोड़ा सावधान करना पड़ता है कि आप इसे कैसे लागू करते हैं, क्योंकि यह इन-प्लेस में काम करता है

  char stack_string[] = "This string is copied onto the stack."; inplace_reverse(stack_string); 

यह ठीक काम करता है, चूंकि stack_string एक सरणी है, जिनकी सामग्री को दिए गए स्ट्रिंग स्थिरांक में आरंभ किया जाता है तथापि

  char * string_literal = "This string is part of the executable."; inplace_reverse(string_literal); 

रनटाइम पर आपके कोड को लौ और मरने का कारण बनता है ऐसा इसलिए है क्योंकि string_literal केवल स्ट्रिंग को इंगित करता है जिसे आपके निष्पादन योग्य के भाग के रूप में संग्रहीत किया जाता है – जो आमतौर पर स्मृति है कि आपको ओएस द्वारा संपादित करने की अनुमति नहीं है। एक खुशहाल दुनिया में, आपका कंपाइलर यह जानता होगा, और जब आप संकलन करने की कोशिश करते हैं तो एक त्रुटि खांसी, आपको बताती है कि string_literal को type char const * क्योंकि आप सामग्री को संशोधित नहीं कर सकते। हालांकि, यह मेरे कंपाइलर की दुनिया में नहीं है।

कुछ ऐसे हैक्स हैं जो आप यह सुनिश्चित करने का प्रयास कर सकते हैं कि कुछ मेमोरी स्टैक या ढेर (और इसलिए संपादन योग्य) पर है, लेकिन वे आवश्यक रूप से पोर्टेबल नहीं हैं, और ये बहुत बदसूरत हो सकता है। हालांकि, मैं फ़ंक्शन इनवॉर्नर के लिए जिम्मेदारी फेंकने के लिए खुश हूं। मैंने उन्हें बताया है कि यह फ़ंक्शन मेमोरी हेरफेर करता है, मुझे यह तर्क देना है कि यह अनुमति देता है।

बस एक पुनर्व्यवस्था, और सुरक्षा जांच मैंने आपके गैर-उपयोग किए गए रिटर्न प्रकार को भी हटा दिया। मुझे लगता है कि यह एक सुरक्षित और साफ है जैसा यह हो:

 #include <stdio.h> #include <string.h> void reverse_string(char *str) { /* skip null */ if (str == 0) { return; } /* skip empty string */ if (*str == 0) { return; } /* get range */ char *start = str; char *end = start + strlen(str) - 1; /* -1 for \0 */ char temp; /* reverse */ while (end > start) { /* swap */ temp = *start; *start = *end; *end = temp; /* move */ ++start; --end; } } int main(void) { char s1[] = "Reverse me!"; char s2[] = "abc"; char s3[] = "ab"; char s4[] = "a"; char s5[] = ""; reverse_string(0); reverse_string(s1); reverse_string(s2); reverse_string(s3); reverse_string(s4); reverse_string(s5); printf("%s\n", s1); printf("%s\n", s2); printf("%s\n", s3); printf("%s\n", s4); printf("%s\n", s5); return 0; } 

संपादित किया जाता है ताकि अंततः संभवतः खराब स्मृति स्थान पर इंगित नहीं किया जा सके, जब स्ट्रेलन 0 हो

आप लूप के लिए अपनी (len/2) परीक्षा डाल सकते हैं:

 for(i = 0,k=len-1 ; i < (len/2); i++,k--) { temp = str[k]; str[k] = str[i]; str[i] = temp; } 

यह पूरा कार्यक्रम दिखाता है कि मैं यह कैसे करूँगा। ध्यान रखें कि मैं सी लिख रहा था जब आप में से ज्यादातर लोग अपनी मां की आँखों में चमक रहे थे, इसलिए यह पुराने स्कूल, काम-द जॉब, लम्बी-वर्-नाम-के-वुम्प्स हैं। तय करें कि यदि आप चाहें, तो मुझे कोड की शुद्धता में अधिक दिलचस्पी है।

यह NULLs, खाली स्ट्रिंग और सभी स्ट्रिंग आकारों को संभालता है। मैंने इसे अधिकतम आकार (अधिकतम (size_t)) के साथ परीक्षण नहीं किया है, लेकिन यह काम करना चाहिए, और यदि आप उस तार को संभालने वाले हैं, तो आप वैसे भी पागल हो 🙂

 #include <stdio.h> #include <string.h> char *revStr (char *str) { char tmp, *src, *dst; size_t len; if (str != NULL) { len = strlen (str); if (len > 1) { src = str; dst = src + len - 1; while (src < dst) { tmp = *src; *src++ = *dst; *dst-- = tmp; } } } return str; } char *str[] = {"", "a", "ab", "abc", "abcd", "abcde"}; int main(int argc, char *argv[]) { int i; char s[10000]; for (i=0; i < sizeof(str)/sizeof(str[0]); i++) { strcpy (s, str[i]); printf ("'%s' -> '%s'\n", str[i], revStr(s)); } return 0; } 

इसका उत्पादन है:

 '' -> '' 'a' -> 'a' 'ab' -> 'ba' 'abc' -> 'cba' 'abcd' -> 'dcba' 'abcde' -> 'edcba' 

इसे इस्तेमाल करे:

 reverse_string(NULL); reverse_string(""); 

आप अपने कोड को कम करने के लिए लूप घोषणा के लिए बदल सकते हैं:

 char* reverse_string(char *str) { char temp; size_t len = strlen(str) - 1; size_t stop = len/2; size_t i,k; for(i = 0, k = len; i < stop; i++, k--) { temp = str[k]; str[k] = str[i]; str[i] = temp; } return str; } 

मुझे एक रिटर्न स्टेटमेंट दिखाई नहीं देता है, और आप इनपुट स्ट्रिंग बदल रहे हैं, जो प्रोग्रामर के लिए एक समस्या हो सकती है। आप चाहते हैं कि इनपुट स्ट्रिंग अपरिवर्तनीय हो।

इसके अलावा, यह पिकदार हो सकता है, लेकिन लेन / 2 को केवल एक बार गणना करना चाहिए, आईएमओ

इसके अलावा, यह काम करेगा, जब तक आप रस्साफैब्रिकेंट द्वारा उल्लिखित समस्या वाले मामलों की देखभाल करते हैं

क्या अब कोई संकेतक का उपयोग नहीं करता है?

 void inplace_rev( char * s ) { char t, *e = s + strlen(s); while ( --e > s ) { t = *s;*s++=*e;*e=t; } } 

संपादित करें: क्षमा करें, बस ऊपर के XOR उदाहरण पर गौर किया …

 void reverse(char *s) { char *end,temp; end = s; while(*end != '\0'){ end++; } end--; //end points to last letter now for(;s<end;s++,end--){ temp = *end; *end = *s; *s = temp; } } 
 rev { int len = strlen(str)-1; for ( int i =0; i< len/2 ; i++ ) { char t = str[i]; str[i] = str[len-i]; str[len-i] = t; } } 
 bool reverse_string(char* str) { // Make sure str is reversible if (!str || strlen(str) < 2) return false; char* first = str; char* last = str + strlen(str) - 1; // Minus 1 accounts for Index offset char temp; do{ temp = *first; *first = *last; *last = temp; } while (++first < --last); // Update Pointer Addresses and check for equality return true; } 

यह समाधान कुछ संशोधनों के साथ GManNickG के पोस्ट पर आधारित है। शुरुआती तार्किक कथन खतरनाक हो सकता है अगर str stren ऑपरेशन (एक शून्य पीटीआर के लिए) से पहले इसका मूल्यांकन नहीं किया जाता है। यह मेरे कंपाइलर के साथ ऐसा नहीं था। मैंने सोचा कि मैं इस कोड को जोड़ दूंगा क्योंकि यह डू-ऑल लूप का एक अच्छा उदाहरण है।

चूंकि आप कहते हैं कि आप कल्पना करना चाहते हैं, शायद आप XOR स्वैप का उपयोग करके अपने पात्रों का आदान-प्रदान करना चाहते हैं।

आधे रास्ते को तोड़ने के बजाय, आपको अपने लूप को छोटा करना चाहिए।

 size_t length = strlen(str); size_t i; for (i = 0; i < (length / 2); i++) { char temp = str[length - i - 1]; str[length - i - 1] = str[i]; str[i] = temp; } 
 #include <stdio.h> #include <string.h> int main() { char *data = "hello world"; int length=strlen(data); char bytes[length]; int n=0; while(n<=length) { bytes[n] = data[length-n-1]; n++; } printf("%s\n", bytes); return 0; } 
 #include <stdio.h> int main() { char string[100]; int i; printf("Enter a string:\n"); gets(string); printf("\n"); for(i=strlen(string)-1;i>-1;i--) printf("%c",string[i]); } 
 Here is my shot which will handle all the cases char *p ="KDLAKDADKADAD" char p[] = "lammdlamldaldladadada" also empty string #include<stdio.h> #include<string.h>enter code here #include<stdlib.h> char *string_reverse(char *p); int main() { char *p = " Deepak@klkaldkaldkakdoroorerr"; char *temp = string_reverse(p); printf("%s", temp); } char * string_reverse( char *p ) { if(*p == '\0') { printf("No charecters are present \n"); return 0; } int count = strlen(p)+1; int mid = strlen(p)/2; char *q = (char *)malloc(count * sizeof(char)); if( q ) { strcpy(q,p); char *begin,*end,temp; begin = q ; end = q+strlen(p)-1 ; int i = 0; while( i < mid/2 ) { temp = *end; *end = *begin; *begin = temp; begin++; end--; i++; } return q; } else { printf("Memory Not allocated "); } free(q); } 
 /* Author: Siken Dongol */ #include <stdio.h> int strLength(char *input) { int i = 0; while(input[i++]!='\0'); return --i; } int main() { char input[] = "Siken Man Singh Dongol"; int len = strLength(input); char output[len]; int index = 0; while(len >= 0) { output[index++] = input[--len]; } printf("%s\n",input); printf("%s\n",output); return 0; } 

कोड अनावश्यक रूप से जटिल दिखता है यहां मेरा संस्करण है:

 void strrev(char* str) { size_t len = strlen(str); char buf[len]; for (size_t i = 0; i < len; i++) { buf[i] = str[len - 1 - i]; }; for (size_t i = 0; i < len; i++) { str[i] = buf[i]; } } 

आसान और सरल कोड xD

 void strrev (char s[]) { int i; int dim = strlen (s); char l; for (i = 0; i < dim / 2; i++) { l = s[i]; s[i] = s[dim-i-1]; s[dim-i-1] = l; } } 

यहाँ मेरा शॉट है मैं सिर्फ मानक strcpy पैटर्न का उपयोग करके गमागमन से बचता हूं:

 char *string_reverse(char *dst, const char *src) { if (src == NULL) return NULL; const char *src_start = src; char *dst_end = dst + strlen(src); *dst_end = '\0'; while ((*--dst_end = *src_start++)) { ; } return dst; } 

और यहाँ एक चल उदाहरण है ।

मेरे दो सेंट:

 /* Reverses n characters of a string and adds a '\0' at the end */ void strnrev (char *txt, size_t len) { size_t idx; for (idx = len >> 1; idx > 0; idx--) { txt[len] = txt[idx - 1]; txt[idx - 1] = txt[len - idx]; txt[len - idx] = txt[len]; } txt[len] = '\0'; } /* Reverses a null-terminated string */ void strrev (char *txt) { size_t len = 0; while (txt[len++]); strnrev(txt, --len); } 

टेस्ट # 1strrev() :

 char string[] = "Hello world!"; strrev(string); printf("%s\n", string); // Displays "!dlrow olleH" 

टेस्ट # 2strnrev() :

 char string[] = "Hello world!"; strnrev(string, 5); printf("%s\n", string); // Displays "olleH" 

आप इस सूचक अंकगणितीय कोशिश कर सकते हैं:

 void revString(char *s) { char *e = s; while(*e){ e++; } e--; while(e > s){ *s ^= *e; *e ^= *s; *s++ ^= *e--; } }