2015-05-17 68 views
0

我知道這個問題非常普遍,解決方案是衆所周知的。但是很長一段時間,我遇到了一個我無法弄清楚的錯誤。我試圖在C中反轉字符串。我的代碼如下:字符串翻轉錯誤

#include <stdio.h> 

char *reverse(char *); 

int main(void) { 

    char str[] = "Hello"; 
    char *rev; 

    rev = reverse(str); 
    printf("The reversed string is %s", rev); 
    return 0; 
} 

char *reverse(char *str){ 

    char *end = str; 
    char tmp; 

    if(str){ 
     while(*end){ 
      ++end; 
     } 
     --end; 

     while(str < end){ 

      tmp = *str; 
      *str++ = *end; 
      *end-- = tmp; 



     } 
    } 
    return str; 
} 

因此,我得到「leH」,而不是「olleH」。任何人都可以指出爲什麼?

+0

我建議你用調試器逐步執行代碼,問題可能會很明顯。 (另外這是一個很好的練習)。 – jpw

+0

爲什麼不使用調試器並逐步完成?你絕對應該學會使用調試器,這對於程序員來說是必須的。 – m0skit0

回答

0

因爲你返回遞增的指針,用另一種指針或索引符號,它會工作,像這樣

char *reverse(char *str) 
{ 
    char *end; 
    char tmp; 
    int i; 

    end = str; 
    if ((str == NULL) || (*str == '\0')) 
     return str; 
    while (*end != 0) 
     ++end; 
    --end; 

    i = 0; 
    while (str + i < end) 
    { 
     tmp  = str[i]; 
     str[i++] = *end; 
     *end-- = tmp; 
    } 
    return str; 
} 

當您返回str,它不再在字符串的開頭指出。

+1

'if(str == NULL)return NULL;' - >'if(!str ||!* str)return str;' – BLUEPIXY

+2

'i'的類型應該是'size_t'。 'reverse(「」);'調用未定義的行爲。 – chqrlie

2

您在reverse()中返回的指針str未指向字符串的開頭,而是指向循環結尾的中間某處。

您的函數的另一個問題是如果您傳遞空字符串:end從字符串的末尾遞減並指向字符串外部。這會調用未定義的行爲。

您應該使用2個臨時指針來執行任務:

char *reverse(char *str) { 
    if (str && *str) { 
     char *p = str; 
     char *end = p + strlen(p) - 1; 

     while (p < end) { 
      char tmp = *p; 
      *p++ = *end; 
      *end-- = tmp; 
     } 
    } 
    return str; 
} 

或者,如果你喜歡使用索引變量:

char *reverse(char *str) { 
    if (str && *str) { 
     for (size_t i = 0, j = strlen(str); i < --j; i++) { 
      char tmp = str[i]; 
      str[i] = str[j]; 
      str[j] = tmp; 
     } 
    } 
    return str; 
} 
0

實現逆轉串的另一種方法是這樣的:

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

char *reverse(const char *); 

int main(void){ 
    char *s = "hello world"; 
    char *s_rev = reverse(s); 
    printf("%s => %s", s, s_rev); 
    free(s_rev); 
    return 0; 
} 
char *reverse(const char *s){ 
    char *s_new = strdup(s); 
    char *s_begptr = &s[0]; 
    char *s_endptr = &s[strlen(s) - 1]; 
    char *ptr = NULL; 
    for (ptr = s_endptr; ptr >= s_begptr; ptr--, s_new++){ 
     *s_new = *ptr; 
    } 
    *s_new = '\0'; 
    s_new -= strlen(s); 
    return s_new; 
} 

注意我們沒有使用任何臨時變量來存儲值,而是使用start並結束相同字符串的指針,並使用循環從字符串的末尾反向工作。