-1

This is a C program for tic tac toe. It works fine but if you enter a character in your turn, it repeats for infinite time. I know I can't enter a character in %d but that's the task I've been given, that if someone enters a character it should not accept it, and asks for the turn again, like it does when I enter a number other than 1-9. HELP

#include<stdio.h>
#include<conio.h>
#include <cstdlib>
#include <string.h>
int main()
{
  int a, player, winner, row, column, line, go;
  char z;
  do
  {
    char name1[20];
    char name2[20];
    printf("\nEnter Player 1 name");
    scanf("%s", name1);
    printf("\nEnter Player 2 name");
    scanf("%s", name2);
    char board[3][3] =
        {
            {'1', '2', '3'},
            {'4', '5', '6'},
            {'7', '8', '9'}
        };
    winner = 0;
    for (a = 0; a < 9 && winner == 0; a++)
    {
      printf("\n\n");
      printf("\t %c | %c | %c \n", board[0][0], board[0][1], board[0][2]);
      printf("\t-----------\n");
      printf("\t %c | %c | %c \n", board[1][0], board[1][1], board[1][2]);
      printf("\t-----------\n");
      printf("\t %c | %c | %c \n", board[2][0], board[2][1], board[2][2]);
      player = a % 2 + 1;
      do
      {
        if (player == 1)
          printf("\nPlayer %s enter the number of square(from 1 to   9)", name1);
        else if (player == 2)
          printf("\nPlayer %s enter the number of square(from 1 to 9)", name2);
        scanf("      %d     ", &go);
        if (go > 0 && go < 10)
        {
          row = --go / 3;
          column = go % 3;
          break;
        }
      }
      while (go < 0 || go > 9 || board[row][column] > '9' || (go >= 'a' && go <= 'z') || (go >= 'Z' && go <= 'Z'));
      if (player == 1)
        board[row][column] = 'X';
      else
        board[row][column] = 'O';

      if ((board[0][0] == board[1][1] && board[0][0] == board[2][2]) ||
          (board[0][2] == board[1][1] && board[0][2] == board[2][0]))
      {
        winner = player;
      }
      else
      {
        for (line = 0; line < 3; line++)
        {
          if ((board[line][0] == board[line][1] && board[line][0] == board[line][2]) ||
              (board[0][line] == board[1][line] && board[0][line] == board[2][line]))
            winner = player;
        }
      }

    }
    if (winner == 0)
      printf("\nDRAW");
    printf("\n\n");
    printf("\t %c | %c | %c \n", board[0][0], board[0][1], board[0][2]);
    printf("\t-----------\n");
    printf("\t %c | %c | %c \n", board[1][0], board[1][1], board[1][2]);
    printf("\t-----------\n");
    printf("\t %c | %c | %c \n", board[2][0], board[2][1], board[2][2]);
    if (winner == 1)
      printf("player %s \n YOU WON !!!", name1);
    else if (winner == 2)
      printf("player %s \n YOU WON !!!", name2);
    printf("\nDo u want to repeat(Y/N)");
    z = getch();
    system("cls");
  }
  while (z == 'y' || z == 'Y');
  getch();
  return (0);
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129

4 Answers4

1

You have to check the return value of scanf to see if it read something.

It will stop reading when it finds a character that cannot be part of a number. The next time through the loop, the offending character will still be there and it fails again. And again.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
1

Closely related topic: Why is scanf() causing infinite loop in this code?

The reason is that if scanf fails to read the pattern it doesn't empty the input buffer, you have to do it manually.

Community
  • 1
  • 1
erdeszt
  • 799
  • 5
  • 12
  • how. plz explain. i just learnt C language, not an expert in it. a lil more detail would be great. – Taimoor Aftab Dec 10 '15 at 15:11
  • There's plenty of information in the linked topic which also links to this document: http://www.cs.utah.edu/~zachary/isp/tutorials/io/io.html – erdeszt Dec 10 '15 at 17:23
1

Well, if you use scanf("%d",&some_variable);, and if the user inputs a number, the scanf function will return 1 and if the user enters a character, it will return 0.

So the following check can be performed

if(scanf("%d",&variable_name)==1)
{
    // this means the input is an integer, fine.
}
else
{
   // this means the input is a character, put some error handling here.
}
Anish Sharma
  • 495
  • 3
  • 15
0

Read the man page for scanf and check what error value are you getting. http://linux.die.net/man/3/scanf