2013-07-27 253 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');'。 –