2014-09-03 156 views
0

因此,這是我第一次在這裏發帖,我會盡力確保儘可能具體。 我必須讓我的學校計劃,說:程序在關閉時崩潰

首先編寫一個函數,得到一個字符,並返回:

  1. 如果它是一個大寫字母相同的字符。
  2. 大寫字母,如果它是小寫字母。
  3. 反斜槓('\'),如果它是一個數字。
  4. 其他情況下的星號('*')。

然後,使用你的函數,讓一個程序得到一個字符串,並在函數改變它之後重新打印它。它應該繼續詢問一個新的字符串,直到用戶鍵入'QUIT',在這種情況下,將打印'再見!'然後退出。

這裏是我的代碼:

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

char fnChange(char c) 
{ 
    if (c > 'a'-1 && c < 'z'+1) 
      c = c - 32; 
    else if (c > '0'-1 && c < '9'+1) 
      c = '\\' ; 
    else if (c > 'A'-1 && c < 'Z'+1) 
      c = c; 
    else 
      c = '*'; 
    return c; 
} 


int main() 
{ 
    int i, refPoint; 
    char *str = (char*)malloc(10); 
    //without the next one, the program crashes after 3 repeats. 
    refPoint = str; 
    while (1==1) {    
     printf("Give a string: "); 
     str = refPoint;//same as the comment above. 
     free(str); 
     scanf("%s",str); 
     if (*str == 'Q' && *(str+1) == 'U' && *(str+2) == 'I' && *(str+3) == 'T') { 
      // why won't if (str == 'QUIT') work? 
      free(str); 
      printf("Bye!");  //after printing "Bye!", it crashes. 
      system("pause"); //it also crashes if i terminate with ctrl+c. 
      exit(EXIT_SUCCESS); //or just closing it with [x]. 
     }  
     printf("The string becomes: "); 
     while (*str != '\0') { 
      putchar(fnChange(*str)); 
      str++; 
     } 
     printf("\n"); 
    } 
} 
+2

'str = refPoint' ????? – 2014-09-03 09:05:55

+1

'free(str)'然後'scanf(「%s」,str)'?????你到底想要發生什麼? – 2014-09-03 09:06:55

+0

一個小點(你的代碼有*真正的問題,見下面的Joachim的答案),而不是'c>'a'-1',你應該寫'c> ='a''。或者,甚至更好,只需使用['islower()'](http://linux.die.net/man/3/islower)。 – unwind 2014-09-03 09:12:25

回答

1

有多種原因會導致崩潰。按照您的代碼,或多或少:

free str然後做一個scanf到它。一旦你釋放了內存,它就不再可用了。

然後scanf:scanf("%s", str)。只要有人在控制檯輸入了10個或更多字符的字符串,就會輸入未定義行爲的領域,因爲內存將被覆蓋。

指定strrefpoint,反之亦然應該給你編譯器警告的負載。其中一個變量是int,另一個是char *。在某些體系結構中,指針不適合int,並且只要您使用它,程序就會崩潰。

您的while循環遞增str。沒有來自refpoint的(危險)拷貝,你最終會試圖釋放一個不是malloc的結果的指針。這是未定義的行爲,可能會崩潰。

在傳:

請不要投malloc結果。它返回一個void *,並且在C中,您可以將void *分配給任何東西,並且不必要的轉換會降低代碼的可讀性。演員意味着你正在做一些不尋常的事情,而這個任務不是。

你不能這樣做str == 'QUIT',因爲C編譯器會比較字符串的地址和 - 鍵入'QUIT'的效果是依賴於編譯器的。它可能會將它與'Q'的字符值進行比較。即使使用str == "QUIT",它也會將指針str(即malloc返回的地址)的值與字符串「QUIT」的地址進行比較,該字符串將在鏈接器設計用於存儲它的任何位置。 C不會進行字符串比較,因此您必須使用strcmp

5
free(str); 
scanf("%s",str); 

沒有沒有沒有,你是不是允許使用動態分配的內存你已經被釋放後。最重要的是,你可以在循環中再次釋放它

這樣做是未定義的行爲。這幾乎肯定是你的崩潰的原因。

其他一些問題。您可以使用<=而不是<使你的代碼更易讀,如用:

if ((c >= 'a') && (c <= 'z')) ... 

使用魔法號碼,如32幾乎總是一個壞主意。只要你正在使用的編碼,其中字母是連續的(如ASCII),你可以這樣做:

c = c - 'A' + 'a'; 

把大寫小寫成。

真的應該然而在幹什麼,使用toupper()tolower()(和isupper()islower()爲好,檢測的情況下),因爲字母保證是連續的。

表達式str == 'QUIT'不會做你認爲的,因爲'QUIT'不是字符串。相反,它是一個多字節字符文字。然而,即使str == "QUIT"不會做你的想法,因爲在C字符串比較正確的做法是:

if (strcmp (str, "QUIT") == 0) ... 
4

你在你的代碼有undefined behavior多例。

首先給指定一個整型變量指針。這些不是真正兼容的(例如,如果int的大小是32位並且指針的大小是64位,會發生什麼情況)。

然後在使用它之前釋放分配的指針,從而寫入未分配的內存。

然後再次在同一個指針上調用free