2013-07-27 5 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

그것을 enter를 누르면 "\ 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을 반환하지 않으므로주의해야합니다.

당신은 다른 getchar에 의해 중이 문제를 해결하거나이 같은 scanf를 사용할 수 있습니다

scanf("%c ", &user); 

주에게 공간을 위의 형식으로 c, 그것은 읽고 무시 후행 공백을 scanf을 알려줍니다 후.

예를 들어 다음과 같은 행을 읽을 수도 있습니다. fgets을 입력 한 다음 해당 행에서 간단한 sscanf을 사용하면 추가 공간이 필요하지 않습니다.

+0

하지만 더 좋은 것은'int''user'입니다. –

+0

또 다른 getchar()을 사용한다는 것은 무엇을 의미합니까? 그러나 SO가 나를 허용하자마자 나는 그것을 받아 들일 것이다. –

+0

@C_Beginner_Learner 원하는 문자를 얻기위한'getchar'과 개행을 가져오고 (그리고 버리는) 것이 있습니다. –

1

입력 버퍼에 개행 문자가 있습니다.

[xx]가 아니고 [oO]가 아닌 문자를 누른 다음 줄 바꿈을 따라야합니다. getchar은 실제로 2 개의 문자 (개행과 유효하지 않은 문자)를 보게됩니다.

문자 입력에 의존하고 매번 getchar() 호출로 개행을 무시하는 대신 fgets을 사용할 수 있습니다.

3

문제의 원인이 대신 getchar()

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

를 사용하는이 방법으로 사용 scanf()

개행 charachter 관련이 당신은 예를 들어 다음과 같은 문제를 해결할 수 : 아마

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'기호가 출력됩니다 (이번에는 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'|| 사용자 == 'o') return ('O'); return ('X');'. –

관련 문제