2016-04-26 44 views
2

我正在構建一個需要在if/else語句中使用典型「y/n」字符函數的長程序,它工作正常,但如果用戶放入某些無效的東西,它會重複我的「無效答案」字符串,等於他們放入的字符數。我嘗試了「%1s」而不是%c,但這並不能阻止失控輸入。如何停止c中char的重複無效答案?

#include<stdio.h> 

int main() 
{ 
printf("Welcome.I can predict the future\n" 
    "I learned this gift from someone in the future.\n" 
    "A bright creature with green eyes taught me how.\n" 
"It appeared to me on a Sunday without enthusiam\n" 
    "and told me I would end up trapped in a computer,\n" 
"and there was nothing I could do about it.\n" 

"It was really cruel of it to do that.\n" 
"I could have enjoyed the rest of my days\n" 
"without being depressed having known that...\n" 
"I also didn't need to know so many other things I\n" 
"now have learned.\n\n" 

"Having said this, would you like me to predict you\n" 
    "future?y/n\n"); 

char ansr; 
scanf("%1s", &ansr); 


while (ansr != 'y' && ansr != 'n'){ 

printf("Invalid answer, Please try again."); 
scanf("%1s", &ansr); 
} 

if (ansr == 'y') { 
printf("You've been warned.\n\n"); 
} 
else if (ansr == 'n') { 
printf("Goodbye Then.\n\n"); 
} 




return 0; 

} 
+0

'char ansr [2]; scanf(「%1s」,ansr); while(* ansr!='y'&& * ansr!='n'){' – BLUEPIXY

+0

使用:'char ansr; 012fscanf(「%1s」,&ansr);'錯誤;'%1s'需要一個指向2個字符的指針,一個用於字符,另一個用於字符串末尾的空值。 (「%c」,&answer)== 1){... OK ...} else {... EOF or error ...}'注意格式字符串中的前導空格,並且沒有尾部空格或空白字符;兩者都很重要 –

回答

1

首先,你不希望使用%1schar因爲這種格式符需要一個數組。在ansr的內存位置寫入1個字符後,它將在下一個內存位置寫入空字節。這導致了未定義的行爲。堅持使用%c

要清除多餘的字符,您希望在循環中使用getchar來讀取字符,直到找到換行符。這將沖洗緩衝區。

while (ansr != 'y' && ansr != 'n') { 
    printf("Invalid answer, Please try again."); 
    while (getchar() != '\n'); 
    scanf("%c", &ansr); 
} 

輸出:

... 
Having said this, would you like me to predict you 
future?y/n 
bogus 
Invalid answer, Please try again.wrong 
Invalid answer, Please try again.yep 
You've been warned. 
0

處理字符串在你的輸入,你可以嘗試從標準到您的ansr緩衝區中讀取如下,然後執行字符串比較。通過將stdin中的其餘內容與%*[^\n]一起扔掉,掃描不受空白或多個字符的影響,並且您將得到所需的y/n字符。另外不要忘記你的大括號,並在main返回零。

#include <stdio.h> 
#include <string.h> 
#define buffLen 32 

int main() {   

    char ansr[buffLen] = ""; 

    printf("...would you like me to predict your future? (y/n) \n"); 

    while (strcmp(ansr, "y") != 0 && strcmp(ansr, "n") != 0){ 

     // Read the string, and throw away the rest up to the newline char. 
     scanf("%s%*[^\n]", &ansr); 

     if (strcmp(ansr, "y") == 0) { 
      printf("You've been warned.\n"); 
     } else if (strcmp(ansr, "n") == 0) { 
      printf("Goodbye Then.\n"); 
     } else { 
      printf("Invalid answer, Please try again.\n"); 
     } 
    } 

    return 0; 
} 

編輯:有在使用do-while循環,我們從虛擬的東西初始化緩衝ansr保存評論一個很好的建議,因爲do塊初始化緩衝區前的狀態是評估。我喜歡這個,因爲我很少考慮使用這些,但這是什麼時候使用它的很好的例子...

#include <stdio.h> 
#include <string.h> 
#define buffLen 32 

int main() { 

    char ansr[strLen]; 

    printf("...would you like me to predict your future? (y/n) \n"); 

    do { 
     // Read the string, and throw away the rest up to the newline char. 
     scanf("%s%*[^\n]", &ansr); 

     if (strcmp(ansr, "y") == 0) { 
      printf("You've been warned.\n"); 
     } else if (strcmp(ansr, "n") == 0) { 
      printf("Goodbye Then.\n"); 
     } else { 
      printf("Invalid answer, Please try again.\n"); 
     } 
    } while (strcmp(ansr, "y") != 0 && strcmp(ansr, "n") != 0); 

    return 0; 
} 
+0

你可能想把它轉換成一個do-while循環,正如所寫的,這個程序可能會第一次出現未定義的行爲,或者根本無法運行,因爲它在初始化'ansr'內容之前調用'strcmp()' 。 – duskwuff

+0

opps,很好​​的捕獲,我的意思是初始化它。 – nigel

+0

緩衝區溢出,這個程序有一個很容易發現,在scanf調用,給它一個長度,否則容易受到攻擊 –