function - Using fgets and sscanf in C messed up the program after loop -
i'm programming tic tac toe game in c.
everything seems going okay, implement error handling techniques programs in case user inputs bad data.
i ask user input number between 1-9 fill slot on tic tac toe graph. when used fgets , sscanf together, ran during first game. then, when user selected 'y' or 'y' continue playing new game, seemed if none of variable values refreshed, , causing chaos within program.
any tips?
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> int printmatch(int array[3][3]); int check(int array[3][3]); char y; char y; int complacer = 0; int complacer2 = 0; int main() { { int fill = 0; int j = 0; int slot = 0; int array[3][3]; array[0][0] = 0; array[0][1] = 0; array[0][2] = 0; array[1][0] = 0; array[2][0] = 0; array[1][1] = 0; array[2][1] = 0; array[1][2] = 0; array[2][2] = 0; srand(time(null )); printmatch(array); char line[20]; { { tryagain: printf("\nenter position 1-9(from left right):"); //i using fgets , sscanf error handling technique incase user inputs incompatible data type, after 1st game over, seems code messes functionality of program //fgets(line,sizeof(line),stdin); //sscanf(line,"%d",&slot); //when use scanf data input, fine, limited error handling scanf("%d", &slot); if (slot > 9 || slot < 1) { printf("incorrect data input! try again. \n"); } } while (!(slot > 0 && slot < 10)); switch (slot) { case 1: if (array[0][0] == -1) { printf("\nwoops, try again!"); goto tryagain; } array[0][0] = 1; check(array); break; case 2: if (array[1][0] == -1) { printf("\nwoops, try again!"); goto tryagain; } array[1][0] = 1; check(array); break; case 3: if (array[2][0] == -1) { printf("\nwoops, try again!"); goto tryagain; } array[2][0] = 1; check(array); break; case 4: if (array[0][1] == -1) { printf("\nwoops, try again!"); goto tryagain; } array[0][1] = 1; check(array); break; case 5: if (array[1][1] == -1) { printf("\nwoops, try again!"); goto tryagain; } array[1][1] = 1; check(array); break; case 6: if (array[2][1] == -1) { printf("\nwoops, try again!"); goto tryagain; } array[2][1] = 1; check(array); break; case 7: if (array[0][2] == -1) { printf("\nwoops, try again!"); goto tryagain; } array[0][2] = 1; check(array); break; case 8: if (array[1][2] == -1) { printf("\nwoops, try again!"); goto tryagain; } array[1][2] = 1; check(array); break; case 9: if (array[2][2] == -1) { printf("\nwoops, try again!"); goto tryagain; } array[2][2] = 1; check(array); break; } if (array[0][0] != 0 && array[0][1] != 0 && array[0][2] != 0 && array[1][0] != 0 && array[2][0] != 0 && array[1][1] != 0 && array[2][1] != 0 && array[1][2] != 0 && array[2][2] != 0) { check(array); if (check(array) == 1) { printf("the user wins!\n"); } else if (check(array) == -1) { printf("the computer wins.\n"); } else { printmatch(array); printf("it's draw!\n"); } goto done; } ++fill; label: complacer = rand() % 3; complacer2 = rand() % 3; if (array[complacer][complacer2] == 0) { array[complacer][complacer2] = -1; check(array); } else goto label; ++fill; printmatch(array); int fullcheck = check(array); if (fullcheck == 1) { printf("the user wins!"); break; } if (fullcheck == -1) { printf("the computer wins."); break; } if (fill > 9) break; } while (fill < 10); done: printf("\ndo want continue? y/n\n"); scanf("%c %c", &y, &y); } while ((y == 'y' || y == 'y')); getchar(); return 0; } int printmatch(int array[3][3]) { int i; int j; (i = 0; < 3; i++) { (j = 0; j < 3; j++) { printf("%d\t", array[j][i]); } printf("\n"); } } int check(int array[3][3]) { int settle; if (array[0][0] == 1 && array[1][1] == 1 && array[2][2] == 1) { settle = 1; } else if (array[0][0] == -1 && array[1][1] == -1 && array[2][2] == -1) { settle = -1; } if (array[0][0] == 1 && array[0][1] == 1 && array[0][2] == 1) { settle = 1; } else if (array[0][0] == -1 && array[0][1] == -1 && array[0][2] == -1) { settle = -1; } if (array[0][2] == 1 && array[1][2] == 1 && array[2][2] == 1) { settle = 1; } else if (array[0][2] == -1 && array[1][2] == -1 && array[2][2] == -1) { settle = -1; } if (array[0][1] == 1 && array[1][1] == 1 && array[2][1] == 1) { settle = 1; } else if (array[0][1] == -1 && array[1][1] == -1 && array[2][1] == -1) { settle = -1; } if (array[1][0] == 1 && array[1][1] == 1 && array[1][2] == 1) { settle = 1; } else if (array[1][0] == -1 && array[1][1] == -1 && array[1][2] == -1) { settle = -1; } if (array[0][0] == 1 && array[1][0] == 1 && array[2][0] == 1) { settle = 1; } else if (array[1][0] == -1 && array[1][1] == -1 && array[1][2] == -1) { settle = -1; } if (array[2][0] == 1 && array[1][1] == 1 && array[0][2] == 1) { settle = 1; } else if (array[1][0] == -1 && array[1][1] == -1 && array[1][2] == -1) { settle = -1; } if (array[2][0] == 1 && array[2][1] == 1 && array[2][2] == 1) { settle = 1; } else if (array[2][0] == -1 && array[2][1] == -1 && array[2][2] == 1) { settle = -1; } return settle; }
user input evil. when want number, types 'a'. want 'y' or 'n' , input of dozens of letters. kudos trying improve coding defensive error handling.
when using sscanf()
or scanf()
, etc., sure check results
int result; result = sscanf(buffer, "%this %that ...", &var1); if (result != expectedresult) // handle error
mixing fgets()
getchar()
, scanf()
confuse issue. recommend not using fgets()
2. fgets()
line orientated, scanf()
stops before consuming new-line.
its fun type 'y' or 'y' continue, using "letter & enter_key" combo not bad , easier sort out @ first.
the fgets()
sscanf()
pair may have caused hiccup, in end easier sort out. recommend returning style , checking result of sscanf()
.
example
scanf("%d", &slot);
here not know if user typed number before pressing 'enter'. user did type number, scanf() consumes leading spaces , digits, leaves 'enter' next input function. instead:
int scancount; const char *prompt = "\nenter position 1-9(from left right):"; { fputs(prompt, stdout); prompt = "incorrect data input! try again. \n"; // maybe next time around if (fgets(line, sizeof(line), stdin) == null) { // standard input closed or grievous i/o error, let's go home. return 0; } scancount = sscanf(line,"%d",&slot); } while ((scancount != 1) || (slot < 1) || slot > 9));
btw: here little trick test if extra text entered after number "9z". replace scancount = ... slot > 9));
with
char c; scancount = sscanf(line,"%d%[^\n]",&slot, &c); } while ((scancount != 1) || (slot < 1) || slot > 9)); // still scancount != 1
Comments
Post a Comment