2013-07-27 163 views
2

我正在爲C創建一個簡單的Tic Tac Toe,這裏是我遇到問題的一個特殊功能。這應該讓用戶選擇'X'或'O',併爲最藝術作品。但是,如果我輸入了錯誤的符號,則會打印以下語句: 「無效的符號,請重新輸入:」兩次。爲什麼消息打印兩次?

爲什麼和如何我可以解決這個問題?

char assign(void)         
{ 
     char user; 

     printf("Would you like to be X or O (Enter your choice): "); 
     user=getchar(); 
     while(user != 'X' && user != 'x' && user != 'O' && user != 'o') 
     { 
      printf("Invalid symbol, please re-enter: "); 
      user=getchar(); 
     } 
     if(user == 'O' || user == 'o')  return('O'); 
     else if(user == 'X' || user == 'x') return('X');  
} 
+0

它可能捕獲「\ n」字符,當你按回車。 – Lucas

+1

[在while循環中使用getchar()]的可能重複](http://stackoverflow.com/questions/2549701/using-getchar-in-a-while-loop)。還有['while循環複製'printf()'兩次纔得到字符](http://stackoverflow.com/questions/17892383/while-loops-duplicates-printf-two-times-before-getting- to-getchar)今天早些時候。也可能有其他人。 –

回答

4

這是因爲當你使用getchar返回下一個字符,但保留在輸入緩衝區中的換行符。所以下一個getchar返回換行符。

您還應該小心,因爲getchar實際上會返回int而不是char。按上述格式的c,它告訴scanf後讀取和無視尾隨空白

scanf("%c ", &user); 

注意空格:

您可以通過另一個getchar解決這個問題,或者使用scanf這個樣子。

你也可以用例如fgets,然後在該行上使用簡單的sscanf,則不需要額外的空間。

+0

但更好的是使用'int''用戶' –

+0

你是什麼意思使用另一個getchar()?但是,謝謝,只要SO讓我接受它。 –

+0

@C_Beginner_Learner一個'getchar'來獲得你想要的角色,一個獲得(並扔掉)換行符。 –

1

您的輸入緩衝區中有換行符。

當您按下不是[xX]而不是[oO]的字符並按照換行符進行操作時。 getchar實際上會看到2個字符(換行符和無效字符)

您可能想要使用fgets而不是依賴字符輸入並且每次都忽略帶有2個getchar()調用的換行符。

3

問題原因與換行符charachter

使用scanf()以這種方式,而不是使用getchar()

scanf(" %c", &user); 
3

你可以解決它像這樣的例子:

char assign(void) 
{ 
     char user; 
     char throwaway_newline; 

     printf("Would you like to be X or O (Enter your choice): "); 
     user=getchar(); 
     throwaway_newline = getchar(); 
     while(user != 'X' && user != 'x' && user != 'O' && user != 'o') 
     { 
      printf("Invalid symbol, please re-enter: "); 
      user=getchar(); 
      throwaway_newline = getchar(); 
     } 
     if(user == 'O' || user == 'o')  return('O'); 
     else if(user == 'X' || user == 'x') return('X');  
} 
+0

一旦我這樣做,它不會重複行,但是,一旦我重新輸入有效的符號,它會打印出一個奇怪的'u'符號(FYI我在'throwaway_newline = getchar();'之後添加了一個break語句;' –

+0

@C_Beginner_Learner :這不是一個超好的解決方法,說實話(例如,你不能輸入多個符號)我不確定你的'u'字符來自哪裏 – Lucas

+1

如果在循環中添加了「break」,並且字符是不正確的話,那麼你在函數底部沒有實際返回一個值,所以你可能會得到'u'作爲垃圾非返回值。'break'(由@C_Beginner_Learner添加)是不合適的。 'getchar()'可能會導致問題;如果你得到了EOF,你就會有一個無限循環,而且'else if'子句可能會更好,就像普通的'else'或甚至沒有'else'一樣:if(user == 'O'|| user =='o')return('O'); return('X');'。 –