2011-12-23 61 views
0

當我在case 1(換句話說,在一個while循環後)呼叫case 2時,下面的代碼會產生兩個笑臉。然而printSentence();的工作原理應該是在case 1C控制檯應用程序在循環後給出笑臉

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

    char *enterSentence(); 
    void printSentence(char *); 
    char *sentence; 
    int willContinue = 1; 

main() { 
    while (willContinue) { 
    int a; 
    scanf("%d", &a); 
    switch (a) { 
      case 1: 
       getchar(); 
       sentence = enterSentence(); 
       printSentence(sentence); 
       break; 
      case 2: 
       getchar(); 
       printSentence(sentence); 
       break; 
      case 3: 
       willContinue = 0; //exit 
       break; 
       } 
    } 
} 

char *enterSentence() { 
     char temp[999]; 
     gets(temp); 
     return temp; 
     } 

void printSentence(char *asd) { 
     puts(asd); 
     } 
. 
. //more code 
. 

我不知道什麼是這裏的問題,感謝您的幫助..

+0

'句子'在每個循環後似乎都不會被清除。 – Blender 2011-12-23 21:16:47

+1

哦!不要使用'gets()'。它不能安全使用,並已從最新的C標準(C11)中刪除。 – pmg 2011-12-23 21:30:08

回答

5

temp當地的功能enterSentence。它在輸入函數時創建,並在函數終止時被銷燬。

當您返回對象的地址(return temp;)時,它仍然存在並具有該地址,但之後會立即銷燬,並且調用函數會收到指向無效位置的指針。

快速和骯髒的解決方案:讓temp靜態對象,因爲該方案開始,可以活到它結束

static char temp[999]; 

注:static是一個快速和骯髒的解決方案,正如我所說。它最好避免。


編輯

慢速和清潔的解決方案:temp對象移動到調用函數和它的指針傳遞給函數

int main(void) { 
    char temp[999]; 
    /* ... */ 
    enterSentence(temp, sizeof temp); 
    /* ... */ 
} 

size_t enterSentence(char *dst, size_t len) { 
    size_t retlen; 
    fgets(dst, len, stdin); 
    retlen = strlen(dst); 
    if (dst[retlen - 1] == '\n') dst[--retlen] = 0; 
    return retlen; 
} 
+0

非常豐富的答案。謝謝! – Ghokun 2011-12-23 21:27:14

0

存儲在sentence先前值保持原樣。