今天在用C语言写三子棋小游戏,碰到了一个问题。
问题代码如下:
void player_move()
{
printf("请玩家落子!\n");
while (1)
{
int row = 0;
int col = 0;
printf("请玩家输入坐标(row col): ");
scanf("%d %d", &row, &col);
if (row < 1 || row > ROW ||
col < 1 || col > COL)
{
printf("输入不合法,请重新输入!\n");
continue;
}
if (g_borad[row - 1][col - 1] != ' ')
{
printf("输入不合法,请重新输入!\n");
continue;
}
g_borad[row - 1][col - 1] = 'x';
break;
}
}
问题:scanf("%d %d", &row, &col);
如果玩家输入的坐标(row, col)是小数或者是字符,那么就会陷入死循环,屏幕上一直打印“输入不合法,请重新输入!”。
原因:
第一次通过scanf读入整数时,如果输入一个字符或小数,scanf将什么都不读,直接返回0;当再次调用scanf时,上次输入的字符或小数仍旧在输入缓冲区里,所以scanf不等用户输入,就直接返回0,如此往复,就陷入了死循环。
解决方法:
在scanf语句前加上fflush(stdin);就可以了。该语句的作用是刷新输入缓冲区的内容。所以在循环中再次调用scanf前,输入缓冲区的内容(上次输入的内容)就被清空。就不会进入死循环了。
改进后的代码:
void player_move()
{
printf("请玩家落子!\n");
while (1)
{
int row = 0;
int col = 0;
printf("请玩家输入坐标(row col): ");
/*---清空输入缓冲区---*/
fflush(stdin);
int check_input = scanf("%d %d", &row, &col);
if (check_input != 2)
{
printf("输入不合法,请重新输入!\n");
continue;
}
if (row < 1 || row > ROW ||
col < 1 || col > COL)
{
printf("输入不合法,请重新输入!\n");
continue;
}
if (g_borad[row - 1][col - 1] != ' ')
{
printf("输入不合法,请重新输入!\n");
continue;
}
g_borad[row - 1][col - 1] = 'x';
break;
}
}
最后,附上三子棋小游戏的源码:
https://github.com/sss-0916/C/tree/master/三子棋