我正在学习在线编码,并尝试使用do while循环
这是骰子游戏的程序
玩家可以使用最少量1000
进入游戏。
玩家可以获得任意数量的机会。如果dice
的值为1
,则玩家会以一半的金额离开游戏。
如果该值不是1
,则总金额会增加100*value
dice
的倍数。
如果玩家退出,他/她将离开他/她已获得的金额。
#include <stdio.h>
#include <stdlib.h>
int main () {
int cash, dice;
char ch;
printf ("cash\n");
scanf ("%d", &cash);
if (cash < 1000) {
printf ("No\n");
exit (0);
}
else {
do {
printf ("dice\n");
scanf ("%d", &dice);
while (dice < 1 || dice > 6) {
printf ("\n invalid");
printf ("dice\n");
scanf ("%d", &dice);
}
if (dice == 1) {
cash = cash / 2;
break;
}
cash = (dice * 100) + cash;
printf ("Do you want to continue");
scanf ("%c", &ch);
} while (ch == 'y');
}
printf ("won=%d", cash);
return 0;
}
此程序不接受y
或n
输入。
它显示语句do you want to continue
直接去赢得声明。
答案 0 :(得分:1)
您的第二个scanf
正在消耗'\n'
个stdin
dice
字符scanf (" %c", &ch);
只需在格式说明符之前添加空格,您就可以在重新加载用户插入的字符之前使用stdin中的所有字符:
scanf()
以use kartik\widgets\DatePicker
格式,空格,制表符或换行符表示如果有任何要跳过的话,请跳过空格。
答案 1 :(得分:0)
您必须在%c
scanf(" %c", &ch);
答案 2 :(得分:0)
更改您的scanf将解决所有问题
scanf(" %c",&ch); //notice space
答案 3 :(得分:0)
printf ("dice\n");
scanf ("%d", &dice);
这已在缓冲区中留下'\ n',而您对scanf的第二次调用会读取此'\ n'而不是'n'并继续。在阅读角色之前,你必须阅读剩余的'\ n'。
man scanf(3):
The format string consists of a sequence of directives which describe how to process the sequence of input characters. If processing of a directive fails, no
further input is read, and scanf() returns. A "failure" can be either of the following: input failure, meaning that input characters were unavailable, or match‐
ing failure, meaning that the input was inappropriate (see below).
A directive is one of the following:
· A sequence of white-space characters (space, tab, newline, etc.; see isspace(3)). This directive matches any amount of white space, including none, in the
input.
· An ordinary character (i.e., one other than white space or '%'). This character must exactly match the next character of input.
· A conversion specification, which commences with a '%' (percent) character. A sequence of characters from the input is converted according to this speci‐
fication, and the result is placed in the corresponding pointer argument. If the next item of input does not match the conversion specification, the con‐
version fails—this is a matching failure.
有两种选择。
scanf (" %c", &ch);
或
(void) getchar ();
scanf ("%c", &ch);
答案 4 :(得分:0)
您遇到的最大问题是没有考虑输入缓冲区(此处为'\n'
)中的stdin
,这是用户按 Enter 输入dice
后,%c
格式说明符会很乐意将'\n'
作为ch
的用户输入。
下一个问题是ch
应该是int
而不是char
,否则您永远无法测试/陷阱EOF
。
此外,您未能验证return
scanf
以确认任何转化有效。
考虑到使用scanf
获取用户输入相关的问题,您最好使用fgets
获取用户输入并将整行用户输入读入足够大小的缓冲区以进行输入,然后使用sscanf
从缓冲区解析数值(或简单地将'0'
减去一个数字)。
将这些部分放在一起,您可以执行以下操作:
#include <stdio.h>
#include <stdlib.h>
#define BUFLEN 128
int main () {
int ch, cash, dice;
char buf[BUFLEN] = "";
printf ("cash: ");
if (!fgets (buf, BUFLEN, stdin)) { /* read/validate cash */
fprintf (stderr, "error: invalid input - cash.\n");
return 1;
}
if (sscanf (buf, "%d", &cash) != 1) { /* parse cash from buf */
fprintf (stderr, "error: invalid conversion - cash.\n");
return 1;
}
if (cash < 1000) {
printf ("No\n");
return 1;
}
do {
ch = 'n'; /* set/reset ch to exit each iteration */
printf ("dice: ");
if (!fgets (buf, BUFLEN, stdin)) { /* read/validate dice */
fprintf (stderr, "error: invalid input - dice.\n");
break; /* break on EOF */
}
/* parse/validate dice */
if (sscanf (buf, "%d", &dice) != 1 || dice < 1 || dice > 6) {
fprintf (stderr, "error: invalid conversion - dice.\n");
ch = 'y'; /* set ch to 'y' */
continue; /* prompt again, etc */
}
if (dice == 1) {
cash = cash / 2; /* note: truncated division */
break;
}
cash = (dice * 100) + cash;
printf ("\nDo you want to continue? (y/n): ");
if (fgets (buf, BUFLEN, stdin))
ch = *buf; /* simply assign first char */
else
break; /* exit loop on EOF */
} while (ch == 'y');
printf ("\nwon = %d\n\n", cash);
return 0;
}
(注意:验证为每个输入输入少于128个字符的测试)
使用/输入示例
$ ./bin/rfmt
cash: 1200
dice: 7
invalid dice.
dice: 5
Do you want to continue? (y/n): y
dice: 2
Do you want to continue? (y/n): y
dice: 6
Do you want to continue? (y/n): n
won = 2500
查看所有答案,并决定是否要使用scanf
或fgets/sscanf
。两者都是可行的,当您在一次scanf
调用中将读取和解析结合起来时,您只会失去一点灵活性。如果您有任何问题,请告诉我。