Функция зацикливается при вводе нуля - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть функция user_get_movement_index, которая предлагает пользователю ввести позицию от 0 до 8 как часть игры в крестики-нолики.

Этот индекс движения передается в is_position_empty, где он определяет, является ли индекс движениянедопустимый или индекс перемещения уже занят, оба отображают сообщение об ошибке и возвращают false, чтобы вызвать рекурсию user_get_movement_index.

Функции работают правильно, когда один и тот же номер вводится дважды, и ведут себя, как и ожидалось, когда любое другое числовведено, но 0.

Проблема в том, что при вводе 0 возникает цикл сообщения об ошибке неверной позиции.Я не понимаю, как это может быть цикл из is_position_empty.Как это не запрашивает пользователя для ввода в каждом цикле?Почему 0 вызывает этот цикл?

Это потому, что мы сравниваем 0 <0 в is_position_empty? </p>

Я новичок в 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);
}

Работает правильно

Working Correctly

Работает правильно

Working Correctly

Цикл

Looping

У меня логическое значение определяется следующим образом:

enum Bool { False, True };
typedef enum Bool boolean;

Когда я инициализирую все элементыматрицы как «а», проблема все еще сохраняется.Когда вводится правильное движение, вызывается функция 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;

Добавив дополнительный printf в пустом is_position, я могускажем, что вся функция зациклена, но она, похоже, не выходит из is_position_empty, поскольку printf из функции, которую она возвращает user_get_movement, не печатается.Как это возможно?В user_get_movement есть только цикл, а в is_position_empty нет цикла, и цикл только для 0?

1 Ответ

0 голосов
/ 26 апреля 2018

следующий предложенный код:

  1. отсутствует функция main()
  2. отсутствует функция, чтобы определить, был ли победитель и кто выиграл
  3. отсутствует определение game
  4. не имеет каких-либо неожиданных циклов
  5. позволяет избежать проблемы, вызванной наличием «рекурсивной» функции

, и теперь предлагаетсякод:

#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;
}
...