C - 数组未填充时 fgets 挂起
C - fgets hangs when array not filled
我正在使用 fgets()
从 stdin
获取输入,似乎遇到了一些缓冲区溢出问题。我添加了一个 while 循环,这意味着吃掉所有字符,但是我的代码是 运行ning 多次,应该只 运行 一次。
void play_game(void) {
int ch; /* Waste */
/* Max input from fgets */
char c[8];
enum cell_contents board[BOARD_HEIGHT][BOARD_WIDTH];
init_board(board);
while(!is_game_over(board)) {
display_board(board);
printf("Please enter a move [enter Q or ctrl-D to quit]: ");
if(fgets(c, sizeof(c), stdin)) {
printf("Entered: %s\n", c);
struct move calculated_move = calculate_move(c);
if(is_valid_move(calculated_move, board))
player_move(calculated_move, board);
else
printf("That is an invalid move!\n");
}
/* eat excess data */
if (strlen(c) == sizeof(c)-1)
while((ch = fgetc(stdin)) != '\n' && ch != EOF);
/* eat overfilled data */
//read_rest_of_line();
}
printf("Game over!\n");
game_over(board);
}
这是我的结果:
Please enter a move [enter Q or ctrl-D to quit]: E4, C4 gfgfd oigjdfogkf dohdfkho dk
Entered: E4, C4
+---+---+---+
1 | o | o | o |
+---+---+---+
2 | o | o | o |
+---+---+---+---+---+---+---+
3 | o | o | o | o | o | o | o |
+---+---+---+---+---+---+---+
4 | o | . | o | . | . | o | o |
+---+---+---+---+---+---+---+
5 | o | o | o | o | o | o | o |
+---+---+---+---+---++---+---+
6 | o | o | o |
+---+---+---+
7 | o | o | o |
+---+---+---+
A B C D E F G
Please enter a move [enter Q or ctrl-D to quit]: Entered: gfgfd o
That is an invalid move!
+---+---+---+
1 | o | o | o |
+---+---+---+
2 | o | o | o |
+---+---+---+---+---+---+---+
3 | o | o | o | o | o | o | o |
+---+---+---+---+---+---+---+
4 | o | . | o | . | . | o | o |
+---+---+---+---+---+---+---+
5 | o | o | o | o | o | o | o |
+---+---+---+---+---++---+---+
6 | o | o | o |
+---+---+---+
7 | o | o | o |
+---+---+---+
A B C D E F G
Please enter a move [enter Q or ctrl-D to quit]: Entered: igjdfog
That is an invalid move!
+---+---+---+
1 | o | o | o |
+---+---+---+
2 | o | o | o |
+---+---+---+---+---+---+---+
3 | o | o | o | o | o | o | o |
+---+---+---+---+---+---+---+
4 | o | . | o | . | . | o | o |
+---+---+---+---+---+---+---+
5 | o | o | o | o | o | o | o |
+---+---+---+---+---++---+---+
6 | o | o | o |
+---+---+---+
7 | o | o | o |
+---+---+---+
A B C D E F G
Please enter a move [enter Q or ctrl-D to quit]:
通过检查数组中的最后一个字符是否为新行解决了问题。
/* eat excess data */
if (strlen(c) == sizeof(c)-1 || c[sizeof(c)-1] != '\n')
read_rest_of_line();
void read_rest_of_line(void){
int ch;
/* remove all characters from the buffer */
while (ch = getc(stdin), ch != '\n' && ch != EOF);
/* clear the error status of the input pointer */
clearerr(stdin);
}
我正在使用 fgets()
从 stdin
获取输入,似乎遇到了一些缓冲区溢出问题。我添加了一个 while 循环,这意味着吃掉所有字符,但是我的代码是 运行ning 多次,应该只 运行 一次。
void play_game(void) {
int ch; /* Waste */
/* Max input from fgets */
char c[8];
enum cell_contents board[BOARD_HEIGHT][BOARD_WIDTH];
init_board(board);
while(!is_game_over(board)) {
display_board(board);
printf("Please enter a move [enter Q or ctrl-D to quit]: ");
if(fgets(c, sizeof(c), stdin)) {
printf("Entered: %s\n", c);
struct move calculated_move = calculate_move(c);
if(is_valid_move(calculated_move, board))
player_move(calculated_move, board);
else
printf("That is an invalid move!\n");
}
/* eat excess data */
if (strlen(c) == sizeof(c)-1)
while((ch = fgetc(stdin)) != '\n' && ch != EOF);
/* eat overfilled data */
//read_rest_of_line();
}
printf("Game over!\n");
game_over(board);
}
这是我的结果:
Please enter a move [enter Q or ctrl-D to quit]: E4, C4 gfgfd oigjdfogkf dohdfkho dk
Entered: E4, C4
+---+---+---+
1 | o | o | o |
+---+---+---+
2 | o | o | o |
+---+---+---+---+---+---+---+
3 | o | o | o | o | o | o | o |
+---+---+---+---+---+---+---+
4 | o | . | o | . | . | o | o |
+---+---+---+---+---+---+---+
5 | o | o | o | o | o | o | o |
+---+---+---+---+---++---+---+
6 | o | o | o |
+---+---+---+
7 | o | o | o |
+---+---+---+
A B C D E F G
Please enter a move [enter Q or ctrl-D to quit]: Entered: gfgfd o
That is an invalid move!
+---+---+---+
1 | o | o | o |
+---+---+---+
2 | o | o | o |
+---+---+---+---+---+---+---+
3 | o | o | o | o | o | o | o |
+---+---+---+---+---+---+---+
4 | o | . | o | . | . | o | o |
+---+---+---+---+---+---+---+
5 | o | o | o | o | o | o | o |
+---+---+---+---+---++---+---+
6 | o | o | o |
+---+---+---+
7 | o | o | o |
+---+---+---+
A B C D E F G
Please enter a move [enter Q or ctrl-D to quit]: Entered: igjdfog
That is an invalid move!
+---+---+---+
1 | o | o | o |
+---+---+---+
2 | o | o | o |
+---+---+---+---+---+---+---+
3 | o | o | o | o | o | o | o |
+---+---+---+---+---+---+---+
4 | o | . | o | . | . | o | o |
+---+---+---+---+---+---+---+
5 | o | o | o | o | o | o | o |
+---+---+---+---+---++---+---+
6 | o | o | o |
+---+---+---+
7 | o | o | o |
+---+---+---+
A B C D E F G
Please enter a move [enter Q or ctrl-D to quit]:
通过检查数组中的最后一个字符是否为新行解决了问题。
/* eat excess data */
if (strlen(c) == sizeof(c)-1 || c[sizeof(c)-1] != '\n')
read_rest_of_line();
void read_rest_of_line(void){
int ch;
/* remove all characters from the buffer */
while (ch = getc(stdin), ch != '\n' && ch != EOF);
/* clear the error status of the input pointer */
clearerr(stdin);
}