문제

저는 간단한 텍스트 기반 행맨 게임을 개발하려고 합니다. 메인 게임 루프는 각 문자에 추측을 입력하라는 메시지로 시작한 다음 해당 문자가 단어에 있는지 확인하고 해당 문자가 있으면 생명을 앗아갑니다. 그렇지 않습니다.그러나 게임을 실행하면 프롬프트가 매번 두 번씩 나타나고 프로그램은 사용자의 입력을 기다리지 않습니다.또한 생명을 앗아가므로(올바른 입력이면 생명 1개, 그렇지 않은 경우 생명 2개), 가져오는 것은 무엇이든 이전 입력과 동일하지 않습니다.다음은 약간 단순화된 게임 루프입니다.

while (!finished)
{
    printf("Guess the word '%s'\n",covered);

    scanf("%c", &currentGuess);

    i=0;
    while (i<=wordLength)
    {
        if (i == wordLength)
        {
            --numLives;
            printf("Number of lives: %i\n", numLives);
            break;
        } else if (currentGuess == secretWord[i]) {
            covered[i] = secretWord[i];
            secretWord[i] = '*';
            break;
        }
        ++i;
    }

    j=0;
    while (j<=wordLength)
    {
        if (j == (wordLength)) {
            finished = 1;
            printf("Congratulations! You guessed the word!\n");
            break;
        } else {
            if (covered[j] == '-') {
                break;
            }
        }
        ++j;

        if (numLives == 0) {
            finished = 1;
        }

    }
}

나는 문제가 scanf가 뭔가를 취하지 않았는데 뭔가를 취했다고 생각하는 것이라고 가정하지만, 그 이유는 전혀 모릅니다.누구든지 어떤 생각을 가지고 있습니까?저는 Mac OS X 10.5에서 gcc 4.0.1을 사용하고 있습니다.

도움이 되었습니까?

해결책

키보드 입력을 읽을 때 scanf(), 입력은 Enter가 누른 후 읽히지 만 Enter 키에 의해 생성 된 Newline은 호출에 의해 소비되지 않습니다. scanf(). 다음에 표준 입력에서 읽을 때 다음에 당신을 기다리는 Newline이있을 것입니다 (다음으로 만들 것입니다. scanf() 데이터가없는 상태에서 즉시 반환을 호출하십시오).

이를 피하기 위해 코드를 다음과 같은 것으로 수정할 수 있습니다.

scanf("%c%*c", &currentGuess);

그만큼 %*c 단일 캐릭터와 일치하지만 별표는 캐릭터가 어디에도 저장되지 않음을 나타냅니다. 이것은 다음에 전화 할 때 Enter 키에 의해 생성 된 Newline 문자를 소비하는 효과가 있습니다. scanf() 빈 입력 버퍼로 시작합니다.

경고: 사용자가 두 키를 누른 다음 입력을 누르면 scanf() 첫 번째 키 스트로크를 반환하고 두 번째를 먹고 다음 입력 호출을 위해 Newline을 떠납니다. 이와 같은 단점은 그 이유 중 하나입니다 scanf() 그리고 많은 프로그래머들은 친구들을 피합니다.

다른 팁

신생.

루프를 통해 처음으로 Scanf ()는 문자를 읽습니다. 그런 다음 Newline을 읽습니다. 그런 다음 다음 캐릭터를 읽습니다. 반복하다.

어떻게 고치는 지?

scanf ()를 거의 사용하지 않지만 형식 문자열을 사용하는 경우 "%.1s", 그것은 공백을 건너 뛰고 (신생을 포함하여) 백인이 아닌 공간 캐릭터를 읽어야합니다. 그러나 단일 문자보다는 캐릭터 배열을 기대할 것입니다.

char ibuff[2];

while ((scanf("%.1s", ibuff) == 1)
{
    ...
}

문제를 작은 부분으로 나눕니다.

int main(void) {
    char val;
    while (1) {
        printf("enter val: ");
        scanf("%c", &val);
        printf("got: %d\n", val);
    }
}

여기서 출력은 다음과 같습니다.

enter val: g
got: 103
enter val: got: 10

scanf 거기에 또 다른 '10'을 줘?

우리가 우리의 가치에 대한 ASCII 번호를 인쇄 했으므로 ASCII의 '10'은 "Enter"입니다. scanf 또한 "Enter"키를 캐릭터로 가져와야합니다.

물론, 당신을보고 있습니다 scanf 문자열, 당신은 당신의 루프를 통해 매번 단일 문자를 요구하고 있습니다. 제어 캐릭터는 또한 문자로 간주되며 선택됩니다. 예를 들어, 위의 루프에서 "esc"를 누른 다음 "입력"을 누르고 다음을 얻을 수 있습니다.

enter val: ^[
got: 27
enter val: got: 10

단지 추측이지만 Scanf로 단일 문자를 입력하고 있지만 사용자는 별도의 추측 문자로 소비되는 추측과 Newline을 입력해야합니다.

scanf(" %c", &fooBar);

이전의 공간을 주목하십시오 %c. 이것은 앞의 모든 공백과 일치하기 때문에 중요합니다.

Jim과 Jonathan의 말이 맞습니다.

당신이 원하는 것을 수행하기 위해 scanf 라인을 얻으려면 (버퍼에 넣지 않고 개행 문자를 소비하십시오) 나는 그것을 다음과 같이 바꿀 것입니다

scanf("%c\n", &currentGuess);

(참고 \n)

그러나 이에 대한 오류 처리는 끔찍합니다.최소한 1에 대해 scanf의 반환 값을 확인하고, 반환하지 않으면 입력을 무시해야 합니다(경고와 함께).

내가 알아 차린 몇 가지 점.

  • scanf("%c") 1 문자를 읽고 다음 번에 입력 버퍼에 입력을 유지합니다.
  • 당신은 증가하고 있습니다 i 사용자의 캐릭터가 문자와 일치하지 않더라도 secretWord
  • 언제 covered[j] '-'가 된 적이 있습니까?

추측 할 것입니다 : 귀하의 코드는 Newline을 데이터를 입력 할 때 추측 중 하나로 취급됩니다. 통제 할 수없는 오류 처리로 인해 항상 *scanf () 가족을 피했습니다. 대신 fgets ()를 사용한 다음 첫 번째 숯/바이트를 꺼내십시오.

코드에 몇 가지 사항이 있습니다.

  1. scanf는 읽는 항목 수를 반환합니다. 0 또는 EOF를 반환하는 경우를 처리하고 싶을 것입니다.
  2. 내 생각에 사용자가 Letter + Enter를 때리고 두 번째 캐릭터로 Newline을 얻는 것입니다. 쉽게 확인하는 방법은 디버깅 인쇄문 문을 추가하여 어떤 문자가 입력되었는지를 보여주는 것입니다.
  3. 코드는 성냥 문자의 첫 번째 발생, 즉 단어가 "테스트"이고 사용자가 't'를 입력 한 경우에만 일치합니다. 코드는 두 가지가 아니라 첫 번째 't'와 일치합니다. 이를 처리하려면 첫 번째 루프를 조정해야합니다.

캐릭터를 입력하면 whitespace 캐릭터를 입력하여 계속 진행해야합니다. 이 공백 문자는 입력 버퍼에 있습니다. stdin 파일을 읽고 읽습니다 scanf() 기능. 이 문제는이 추가 캐릭터를 소비하여 해결할 수 있습니다. 이것은 Usnig a에 의해 수행 될 수 있습니다 getchar() 기능.

scanf("%c",&currentGuess);  
getchar();   // To consume the whitespace character.

차라리 사용하지 않도록 제안합니다 scanf() 대신 사용합니다 getchar(). 그만큼 scanf()많은 메모리 공간이 필요합니다. getchar() 가벼운 기능입니다. 그래서 당신은 또한 사용할 수 있습니다.

char currentGuess;  
currentGuess=getchar();  
getchar();  // To consume the whitespace character.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top