2013-06-06 103 views
0

我有字符串「helLo,wORld!」我希望我的程序將其更改爲「Hello,World!」。我的程序工作正常,字符改變了,但我在感嘆號之後不斷收到額外的字符。我可能做錯了什麼?在字符串的結尾爲什麼我會在字符串末尾添加額外的字符?

void normalize_case(char str[], char result[]) 
{ 
    if (islower(str[0]) == 1) 
    { 
     result[0] = toupper(str[0]); 
    } 

    for (int i = 1; str[i] != '\0'; i++) 
    { 
     if (isupper(str[i]) == 1) 
     { 
     result[i] = tolower(str[i]); 
     } 

     else if (islower(str[i]) == 1) 
     { 
     result[i] = str[i]; 
     } 

     if (islower(str[i]) == 0 && isupper(str[i]) == 0) 
     { 
     result[i] = str[i]; 
     } 

     if (str[i] == ' ') 
     { 
     result[i] = str[i]; 
     } 

     if (str[i - 1] == ' ' && islower(str[i]) == 1) 
     { 
     result[i] = toupper(str[i]); 
     } 
    } 
} 
+0

額外的人物像什麼? – Patashu

+0

據我可以告訴你不是null終止'結果'。 –

+0

這是混合了特殊字符,如問號和字母。我在想,可能是因爲我沒有在最後加上'\ 0'?我不記得如何做到這一點,但當我問我的導師時,他說在節目結束時加上'\ 0'......:/ – Karen

回答

3

額外隨機ISH字符通常意味着你忘了空終止('\0')的字符串。您的循環會將所有內容複製到結果中,但不包括終端null。

添加result[i] = '\0';之前你回來的循環。

通常,您將isxxxx()函數(宏)視爲返回一個布爾條件,並且確保您只有一條條件執行。你會更仔細地使用else條款來做到這一點。如果代碼爲空白,您的代碼實際上會複製str[i]多次。事實上,我認爲你可以你的循環壓縮到:

int i; 

for (i = 1; str[i] != '\0'; i++) 
{ 
    if (isupper(str[i])) 
     result[i] = tolower(str[i]); 
    else if (str[i - 1] == ' ' && islower(str[i])) 
     result[i] = toupper(str[i]); 
    else 
     result[i] = str[i]; 
} 
result[i] = '\0'; 

如果我把result[i]外面的for循環,不會對編譯器抱怨i

是的,它會的。在這種情況下,您需要在循環控制外部定義i,因爲您需要循環後的值。請參閱上面的修改代碼。

您可能還會注意到,如果循環代碼不是小寫字母,那麼您的循環前代碼會安靜地跳過該字符串的第一個字符,並將垃圾作爲結果的第一個字符。你應該寫:

result[0] = toupper(str[0]); 

這樣總是設置result[0]

+0

如果我把結果[i]放在for循環之外,編譯器會不會抱怨我? – Karen

+0

感謝您的幫助! :) – Karen

2

您不是null終止result因此,當您打印出來它將繼續前進,直到找到空。如果您在for循環之前移動的i的聲明:

int i ; 
for (i = 1; str[i] != '\0'; i++) 

您可以添加:

result[i] = '\0' ; 

for循環結束後,這是假設result足夠大。

+0

哦!我明白了,我是否會說,在for循環結束之前返回'\ 0'?我對如何寫這個有點困惑。 :( – Karen

+0

@凱倫更新了我的答案。 –

+0

感謝您的幫助!:)我已經明白了。 :D – Karen

1

我冒昧地簡化了你的代碼,因爲你做的很多檢查都是不必要的。其他人已經解釋的一些基本要點要牢記:

#include <stdio.h> /* for printf */ 
#include <ctype.h> /* for islower and the like */ 

void normalise_case(char str[], char result[]) 
{ 
    if (islower(str[0])) 
    { 
     result[0] = toupper(str[0]); /* capitalise at the start */ 
    } 

    int i; /* older C standards (pre C99) won't like it if you don't pre-declare 'i' so I've put it here */ 

    for (i = 1; str[i] != '\0'; i++) 
    { 
     result[i] = str[i]; /* I've noticed that you copy the string in each if case, so I've put it here at the top */ 

     if (isupper(result[i])) 
     { 
      result[i] = tolower(result[i]); 
     } 

     if (result[i - 1] == ' ' && islower(result[i])) /* at the start of a word, capitalise! */ 
     { 
      result[i] = toupper(result[i]); 
     } 

    } 

    result[i] = '\0'; /* this has already been explained */ 
} 

int main() 
{ 
    char in[20] = "tESt tHIs StrinG"; 

    char out[20] = ""; /* space to store the output */ 

    normalise_case(in, out); 

    printf("%s\n", out); /* Prints 'Test This String' */ 

    return 0; 
} 
+0

謝謝你方的小解釋!這真的有幫助。 :) – Karen

+0

很高興你發現它很有用,讓我知道如果某一行或其他不明確。 :) – Nobilis

+0

非常感謝你! – Karen

1

你應該因爲C語言在循環的末尾添加語句result[i] = '\0',字符串數組應該用特殊字符「\ 0結束',它告訴編譯器「這是字符串的結尾」。

相關問題