15幻灯片益智游戏:分段错误(核心转储)错误

时间:2017-12-05 21:41:11

标签: c segmentation-fault cygwin

我第一次尝试在这里寻求帮助,所以如果我的问题解释/写得不好,那就太糟糕了。我正在为magic-15益智游戏编写代码,但我认为我的update_board函数出错,导致出现分段错误(核心转储)运行时错误。任何反馈或帮助将不胜感激。很抱歉代码过多,我只是对编程很新,我不能100%确定我的错误在哪里,所以我只把整个代码放在那里。

只是澄清一下,这就是游戏:https://www.youtube.com/watch?v=EtXE08bOVZM

#include <stdio.h>
#include <math.h>
#include <string.h>


//fn that allows user input at game start
void scan_board(int board[4][4]){
    printf("Enter initial board state:\n");

    for (int i = 0; i <= 3; i++){
        scanf("%d %d %d %d", &board[i][0], &board[i][1], &board[i][2], &board[i][3]);
    }
}


//fn that prints the user inputted starting board
void print_board(int board[4][4]){
    for (int i = 0; i <= 3; i++){
        for (int j = 0; j<= 3; j++){
            if (board[i][j] == -1){
                printf("%-2s ", "_");
            }else{
                printf("%-2d ", board[i][j]);
            }
        }
        printf("\n");
    }
}

//fn that updates the game board after the user makes a move and also tells user if their move is invalid
int update_board(const char command[100], int board[4][4]){
    //char up[3] = "up";
    //char down[5] = "down";
    //char left[5] = "left";
    //char right[6] = "right";
    int x, y;
    int check = 1;
    for (int i = 0; i <= 3; i++){
        for (int j = 0; j <= 3; j++){
            if (board[i][j] == -1){
                x = i;
                y = j;
                check = 0;
                break;
            }
        }
        if (check == 0){
            break;
        }
    }
    if (strcmp(command, "up\0" == 0)){
        if (x == 0){
            printf("invalid move\n");
        }else{
            board[x][y] = board[x + 1][y];
            board[x + 1][y] = -1;
        }
    }else if (strcmp(command, "down\0" == 0)){
        if (x == 3){
            printf("invalid move\n");
        }else{
            board[x][y] = board[x - 1][y];
            board[x - 1][y] = -1;
        }           
    }else if (strcmp(command, "left\0" == 0)){
        if (y == 0){
            printf("invalid move\n");
        }else{
            board[x][y] = board[x][y - 1];
            board[x][y - 1] = -1;
        }
    }else if (strcmp(command, "right\0" == 0)){
        if (y == 3){
            printf("invalid move\n");
        }else{
            board[x][y] = board[x][y + 1];
            board[x][y + 1] = -1;
        }
    }else{
        printf("invalid command\n");
    }
}

//fn that checks how many tiles are in the wrong place
int check_state(int board[4][4]){
    int num = 1;
    int count = 0;
    for (int i = 0; i <= 3; i++){
        for (int j = 0; j <= 3; j++){
            if (board[i][j] != num){
                count++;    
            }
            num++;
        }
    }
    count--;
    if (count == 0){
        return 0;
    }else{
        return count;
    }
}

//main fn
int main(void){
    int board[4][4];
    char command[100];
    scan_board(board);
    printf("\n");
    //print_board(board);
    //int state = check_state(board);
    //printf("number of tiles out of position: %d\n\n", state);
    int state = check_state(board);
    while (state > 0){
        print_board(board);
        printf("number of tiles out of position: %d\n\n", state);
        printf("make a move: ");
        gets(command);
        printf("%s\n", command);
        update_board(command, board);
        state = check_state(board);
    }
    printf("final board state\n\n");
    print_board(board);
    printf("you won!");

    return 0;
}

1 个答案:

答案 0 :(得分:1)

就像我在评论中指出的那样,您应该修复所有strcmp次来电。

另一个问题是,您需要将update_board声明为void,因为它不会返回任何内容。

最后一次替换gets,因为fgetsscanf()已弃用,如下所示: fgets(command, 100, stdin);

void scan_board(int board[4][4])内,您应该使用第二个循环而不是使用此行:

scanf("%d %d %d %d", &board[i][0], &board[i][1], &board[i][2], &board[i][3]);

并检查scanf是否有错误:

void scan_board(int board[4][4]){
    printf("Enter initial board state:\n");

    for (int i = 0; i < 4; i++){
        for (int j = 0 ; j < 4 ; j++){
            if ( scanf("%d", &board[i][j] ) != 1 ){
                printf("Error, scanf\n");
            }
        }
    }
}

执行此操作后,它应如下所示:

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>

//fn that allows user input at game start
void scan_board(int board[4][4]);
void scan_board(int board[4][4]){
    printf("Enter initial board state:\n");

    for (int i = 0; i < 4; i++){
        for (int j = 0 ; j < 4 ; j++){
            if ( scanf("%d", &board[i][j] ) != 1 ){
                printf("Error, scanf\n");
                exit(EXIT_FAILURE);
            }
        }
    }
}


//fn that prints the user inputted starting board
void print_board(int board[4][4]);
void print_board(int board[4][4]){
    for (int i = 0; i <= 3; i++){
        for (int j = 0; j<= 3; j++){
            if (board[i][j] == -1){
                printf("%-2s ", "_");
            }else{
                printf("%-2d ", board[i][j]);
            }
        }
        printf("\n");
    }
}

//fn that updates the game board after the user makes a move and also tells user if their move is invalid
void update_board(const char command[100], int board[4][4]);
void update_board(const char command[100], int board[4][4]){
    //char up[3] = "up";
    //char down[5] = "down";
    //char left[5] = "left";
    //char right[6] = "right";
    int x, y;
    int check = 1;
    for (int i = 0; i <= 3; i++){
        for (int j = 0; j <= 3; j++){
            if (board[i][j] == -1){
                x = i;
                y = j;
                check = 0;
                break;
            }
        }
        printf("Y = %d\n", y);
        if (check == 0){
            break;
        }
    }
    if (strcmp(command, "up") == 0){
        if (x == 0){
            printf("invalid move\n");
        }else{
            board[x][y] = board[x + 1][y];
            board[x + 1][y] = -1;
        }
    }else if (strcmp(command, "down") == 0){
        if (x == 3){
            printf("invalid move\n");
        }else{
            board[x][y] = board[x - 1][y];
            board[x - 1][y] = -1;
        }
    }else if (strcmp(command, "left") == 0){
        if (y == 0){
            printf("invalid move\n");
        }else{
            board[x][y] = board[x][y - 1];
            board[x][y - 1] = -1;
        }
    }else if (strcmp(command, "right") == 0){
        if (y == 3){
            printf("invalid move\n");
        }else{
            board[x][y] = board[x][y + 1];
            board[x][y + 1] = -1;
        }
    }else{
        printf("invalid command\n");
    }
}

//fn that checks how many tiles are in the wrong place
int check_state(int board[4][4]);
int check_state(int board[4][4]){
    int num = 1;
    int count = 0;
    for (int i = 0; i <= 3; i++){
        for (int j = 0; j <= 3; j++){
            if (board[i][j] != num){
                count++;
            }
            num++;
        }
    }
    count--;
    if (count == 0){
        return 0;
    }else{
        return count;
    }
}

//main fn
int main(void){
    int board[4][4];
    char command[100];
    scan_board(board);

    printf("\n");
    //print_board(board);
    //int state = check_state(board);
    //printf("number of tiles out of position: %d\n\n", state);
    int state = check_state(board);
    while (state > 0){
        print_board(board);
        printf("number of tiles out of position: %d\n\n", state);
        printf("make a move: ");

        if ( scanf("%99s", command) != 1){
            printf("error scanf, again\n");
            exit(EXIT_FAILURE);
        }

        update_board(command, board);
        state = check_state(board);
    }
    printf("final board state\n\n");
    print_board(board);
    printf("you won!");

    return 0;
}

输出:

Enter initial board state:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

final board state

1  2  3  4  
5  6  7  8  
9  10 11 12 
13 14 15 16 
you won!

我不知道你的程序应该如何表现,但至少你可以编译和测试它。