C语言 使用 scanf() 读取字符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17497111/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:51:59  来源:igfitidea点击:

Reading character with scanf()

ccharscanfspecifier

提问by haccks

This code is for game of craps.

此代码用于掷骰子游戏

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>

int roll_dice(void);
bool play_game(void);

int main()
{
   int i, ch,win = 0,lose = 0;
   bool flag;
   srand((unsigned)time(NULL));

   do
   {
       flag = play_game();
       if(flag)
       {
           printf("You win!");
           win++;
       }
       else
       {
           printf("You lose!");
           lose++;
       }

       printf("\n\nPlay again(Y/N)? ");
       scanf("%c", &ch);
       ch = getchar();
       printf("\n");
   }while(ch == 'Y' || ch == 'y');

   printf("\nWins: %d   Losses: %d",win,lose);
   return 0;
}

int roll_dice(void)
{
    return rand()%6 + rand()%6 + 2;
}

bool play_game(void)
{
   int sum = roll_dice();

   printf("You rolled: %d\n", sum);
   if(sum == 7 || sum == 11)
       return 1;
   else if(sum == 2 || sum == 3 || sum == 12)
       return 0;    
   else
   {
       int point = sum;
       printf("Your point is: %d\n", point);
       do
       {
           sum = roll_dice();
           printf("You rolled: %d\n", sum);
           if(sum == 7)
               return 0;            
       }while(point != sum);
       return 1;
   }                    
}

I have problem only with code snippet

我只有代码片段有问题

 printf("\n\nPlay again(Y/N)? ");
 scanf("%c", &ch);
 ch = getchar();
 printf("\n");

I have used, because it terminates after one iteration whatever user input Yor N. I thought I am doing wrong by placing ch = getchar()to eat up \n, I removed it and placed a space before conversion specifier and replaced it by " %c"which also did't work.When I replaced the conversion specifier by %dit works fine.
Is anything going wrong with this?
I visited this postand it is saying same thing I did.

我使用过,因为无论用户输入YN. 我认为我放置ch = getchar()to eat up做错了\n,我删除了它并在转换说明符之前放置了一个空格并将其替换为" %c"which 也不起作用。当我用%d它替换转换说明符时它工作正常。
这有什么问题吗?
我访问了这篇文章,它说的是我做的同样的事情。

采纳答案by hmjd

The posted code has undefined behaviour because chis of type intand the format specifier %cmust match a char.

发布的代码具有未定义的行为,因为ch它是类型int并且格式说明符%c必须匹配 a char

When I replaced the conversion specifier %d it works fine.

当我替换转换说明符 %d 时,它工作正常。

When you switch to %dthe scanf()fails, because Yor yis not an int, so no input is consumed (apart from leading whitespace which discards the new line character on subsequent iterations of the loop) and the subsequent ch = getchar()actually reads the user entered character, and the code works by fluke. Always check the return value of scanf(), which returns the number of assignments made.

当您切换到%dscanf()失败,因为Y还是y不是int,所以没有投入被消耗(除了前导空格其丢弃在循环的后续迭代的新行字符)和随后的ch = getchar()实际读取用户输入的字符和代码作品侥幸。始终检查 的返回值scanf(),它返回所做的分配数量。

回答by hmjd

scanf("%c", &ch);
ch = getchar();

And that's how you lost the previous char stored in ch. How about

这就是您丢失存储在ch. 怎么样

ch = fgetc(stdin);
while (fgetc(stdin) != '\n')
    ;

instead?

反而?

回答by Paulo1205

You convert the character with scanf(), and then overwrite it with getchar() immediately afterwards. I wouldn't expect it to work, unless you type "yy" before typing ENTER, but then your second confirmation would fail.

scanf()转换字符,然后getchar立即用()覆盖它。我不希望它起作用,除非您在输入 ENTER 之前输入“yy”,但是您的第二次确认将失败。

BTW, use the space in " %c".

顺便说一句,使用" %c".

回答by Orkhan Hasanli

printf("Play again? ");
scanf(" %c", &char);

this code works for me. The project is from K.N.King's "C programming : A modern approach" book. I met with this problem before and had the same problem. On page 224 there is a guess.c example project which includes exactly the same command "ask" ("play again"). And author used scanf(" %c", &command); (he used command instead of ch) and it did work. I remember I used it during the "game of craps" project but it did not work. Probably I missed something. Overall, the expression above 100% does work.

这段代码对我有用。该项目来自 KNKing 的“C 编程:现代方法”一书。我之前遇到过这个问题并且遇到了同样的问题。在第 224 页上有一个 guess.c 示例项目,其中包含完全相同的命令“ask”(“play again”)。作者使用了 scanf(" %c", &command); (他使用命令而不是 ch)并且它确实有效。我记得我在“掷骰子游戏”项目中使用过它,但它不起作用。可能我错过了什么。总体而言,高于 100% 的表达式确实有效。