我有一个user_get_movement_index函数,提示用户输入0到8的位置作为井字游戏的一部分。
此移动索引传递给is_position_empty,在此确定移动索引是无效还是已经采用移动索引,两者都显示错误消息并返回false以触发user_get_movement_index的递归。
当输入两次相同的数字时,函数正确循环,并且当输入任何其他数字但是为0时,其行为与预期一致。
问题是当输入0时会导致无效位置错误消息的循环。 我不明白它是如何从is_position_empty中循环的。 如何在每个循环中不提示用户输入? 为什么0导致这个循环?
是因为我们正在比较0< is_position_empty中的0是什么?
我是C新手和堆栈溢出所以请原谅我的格式化,理解和可怕的代码。
//--------------------------------------------------
// 05. FUNCTION my_getchar (IMPLEMENTED)
//--------------------------------------------------
char my_get_char() {
//1. We create the variable to be returned
char res = ' ';
//2. We create an extra variable to consume any other characters entered until a return is pressed
boolean line_consumed = False;
char dummy_char = ' ';
//3. We consume the first char entered, i.e., the one we are interested at
res = getchar();
//4. While still there are remaining characters
while (line_consumed == False) {
//4.1. We consume the next character
dummy_char = getchar();
//4.2. If the new character is the end of line one, we can ensure we have consumed the entire line.
if (dummy_char == '\n')
line_consumed = True;
}
//5. We return res
return res;
}
//------------------------------------
// 06. FUNCTION is_position_empty
//------------------------------------
boolean is_position_empty(game* g, int pos) {
//1. We create the variable to be returned
boolean res = False;
//2. We check if the index is a valid one and if the board is empty at that index.
//If it is valid and free, we return True.
//Otherwise, we return False and write a warning message.
int row= pos/3;
int column = pos%3;
if (pos<0 || pos>8){
printf("\t Invalid Position. Try again!\n\n");
return res;
}
else if (g->board[row][column]=='X' || g->board[row][column]=='O'){
printf("\t This postion is already busy. Try Again!\n\n");
return res;
}
else{
res=True;
return res;
}
}
//---------------------------------------
// 07. FUNCTION user_get_movement_index
//---------------------------------------
int user_get_movement_index(game* g) {
//2. We create a boolean variable to control that we have received a valid movement index.
boolean validMove=False;
//3. We create a char variable to control the index we are receiving by keyboard.
char indexChar;
int indexInt;
//We print a message asking for a new movement.
printf(" Enter a position 0 to 8: ");
//We call to my_get_char to get the index and we convert it to an integer.
indexChar=my_get_char();
indexInt=indexChar-'0';
//We call to is_position_empty to check that the index is a valid one.
validMove=is_position_empty(g, indexInt);
if (validMove==True)
return indexInt;
else
return user_get_movement_index(g);
}
正确工作
正确工作
循环
我的boolean定义如下:
enum Bool { False, True };
typedef enum Bool boolean;
当我将矩阵的所有元素初始化为“a”时,问题仍然存在。 输入有效移动时,将调用process_movement函数,并将板的相应元素初始化为“X”或“O”。
char mark;
if (g->status==1)
mark='X';
else
mark='O';
int row = pos/3;
int column = pos%3;
g->board[row][column]=mark;
通过在is_position中添加一个额外的printf,我可以告诉整个函数是循环的,但它似乎没有退出is_position_empty,因为它返回到user_get_movement的函数中的printf没有被打印。这怎么可能?在user_get_movement中只有一个循环而在is_position_empty中只有一个循环,并且只有0的循环?
答案 0 :(得分:1)
以下提议的代码:
main()
函数game
现在建议的代码:
#include <stdio.h> // getchar()
#include <stdbool.h> // bool, true, false
#include <ctype.h> // isdigit()
// prototypes
int my_get_char( void );
bool is_position_empty(game* g, int pos);
int user_get_movement_index(game* g);
//--------------------------------------------------
// 05. FUNCTION my_getchar (IMPLEMENTED)
//--------------------------------------------------
int my_get_char()
{
//1. We create the variable to be returned
//3. We consume the first char entered, i.e., the one we are interested at
int res = getchar();
//4. While still there are remaining characters
while ( '\n' != getchar() );
//5. We return res
return res;
}
//------------------------------------
// 06. FUNCTION is_position_empty
//------------------------------------
bool is_position_empty(game* g, int pos)
{
//2. We check if the index is a valid one and if the board is empty at that index.
//If it is valid and free, we return True.
//Otherwise, we return False and write a warning message.
int row= pos/3; = 0
int column = pos%3; = 0
if (pos<0 || pos>8)
{
printf("\t Invalid Position. Try again!\n\n");
return false;
}
else if (g->board[row][column]=='X' || g->board[row][column]=='O')
{
printf("\t This postion is already busy. Try Again!\n\n");
return false;
}
return true;
}
//---------------------------------------
// 07. FUNCTION user_get_movement_index
//---------------------------------------
int user_get_movement_index(game* g)
{
//3. We create a char variable to control the index we are receiving by keyboard.
int indexInt;
do
{
//We print a message asking for a new movement.
printf(" Enter a position 0 to 8: ");
//We call to my_get_char to get the index and we convert it to an integer.
indexInt = my_get_char();
if( isdigit( indexInt ) )
{
indexInt -= '0';
}
else
{
printf( "entry was not in the inclusive range: 0...8\n" );
continue;
}
//We call to is_position_empty to check that the index is a valid one.
} while( !is_position_empty(g, indexInt) );
return indexInt;
}