分段错误(核心已转储),没有编译错误

时间:2018-12-31 21:14:50

标签: c

这是一个程序,用于使用用户输入的参数初始化扫雷器,然后进行打印。当我运行它时(输入参数后),我遇到了分段错误(核心已转储)。但是它编译时没有错误或警告。如何找到错误? 我尝试在Ubuntu终端和Windows 10的dev-C ++中进行编译和运行。有任何想法吗? 预先谢谢你。

//File: 5.2mineboard_setup.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROWS 101            //Μέγιστο επιτρεπόμενο ύψος πίστας
#define COLUMNS 101         //Μέγιστο επιτρεπομενο μήκος πίστας

void welcome(void);
int getRows(void);
int getColumns(void);
int getBombs(int, int);
void initializeBoard(char board[ROWS][COLUMNS], int, int);
void putBombs(char board[ROWS][COLUMNS], int, int, int);
void putNums(char board[ROWS][COLUMNS], int, int);
void putBorder(char board[ROWS][COLUMNS], int, int);
void printBoard(char board[ROWS][COLUMNS], int, int);

int main(void)
{
//  system ("chcp 1253");                   //Uncomment to run in Windows. Comment to run on Unix
    int Rows, Columns, Bombs;
    char Board[ROWS][COLUMNS];
    welcome();                              //Μήνυμα υποδοχής
    Rows = getRows();                       //Πλήθος γραμμών
    Columns = getColumns();                 //Πλήθους στηλών
    Bombs = getBombs(Rows, Columns);        //Εισαγωγή πλήθους βομβών
    initializeBoard(Board, Rows, Columns);  //Αρχικοποίηση του πίνακα με χαρακτήρες κενού
    putBombs(Board, Rows, Columns, Bombs);  //Τυχαία τοποθέτηση βομβών (όχι στις ακραίες στήλες και σειρές)
    putNums(Board, Rows, Columns);          //Καταμέτρηση βομβών σε γειτονικά τετράγωνα
    putBorder(Board, Rows, Columns);        //Τοποθέτηση περιγράμματος πίστας
    printBoard(Board, Rows, Columns);       //Εκτύπωση πίστας
    return 0;
}

//Τίτλος προγράμματος
void welcome(void)
{
    printf("Δημιουργία πίστας ναρκαλιευτή\n");
    printf("=============================\n\n");
}   

//Εισαγωγή ύψους πίστας
int getRows(void)
{   
    int rows;
    printf("Εισάγετε ύψος πίστας από 1 ως %d: \n", (ROWS-2));
    scanf ("%d",&rows);
    while(rows>(ROWS-2))    //Έλεγχος αν το ύψος υπερβαίνει το μέγιστο επιτρεπόμενο
    {
        printf("Υπερβολικά μεγάλο ύψος. Εισάγετε νέο ύψος: \n");
        scanf("%d",&rows);          
    }
    return rows;
}   

//Εισαγωγή μήκους πίστας
int getColumns(void)
{
    int columns;
    printf("Εισάγετε μήκος πίστας από 1 ως %d: \n", (COLUMNS-2));
    scanf ("%d",&columns);
    while(columns>(COLUMNS-2))  //Έλεγχος αν το μήκος υπερβαίνει το μέγιστο επιτρεπόμενο
    {
        printf("Υπερβολικά μεγάλο μήκος. Εισάγετε νέο μήκος: \n");
        scanf("%d",&columns);           
    }
    return columns;
}   

//Εισαγωγή αριθμού βομβών
int getBombs(int r, int c)
{   
    int bombs;
    printf("Εισάγετε πλήθος βομβών από 1 ως %d: \n", (r*c));
    scanf ("%d",&bombs);
    while(bombs>(r*c))  //Έλεγχος αν χωράνε οι βόμβες
    {
        printf("Όπα, δε χωράνε τόσες βόμβες. Εισάγετε νέο πλήθος βομβών: \n");
        scanf("%d",&bombs);         
    }
    return bombs;
}

//Αρχικοποίησε πίνακα με χαρακτήρες κενού
void initializeBoard(char board[ROWS][COLUMNS], int rows, int columns)
{
    int i, j;
    for(i=0; i<(ROWS); i++)
        for(j=0; j<(COLUMNS); j++)
            board[i][j] = ' ';
}

/*Τοποθέτησε x βόμβες σε τυχαίες θέσεις
(όχι στο περίγραμμα), προσεχοντας να μη συμπέσουν*/
void putBombs(char board[ROWS][COLUMNS], int rows, int columns, int bombs)
{
    int i, j, k;
    srand(time(NULL));
    for(k=0; k<bombs; k++)              //Επανάλαβε τόσες φορές όσες οι βόμβες
    {
        do
        {
            i = 1 + rand()/rows;        //Τυχαία επιλογή γραμμής
            j = 1 + rand()/columns;     //Τυχαία επιλογή στήλης
        }
        while(board[i][j] != ' ');      //Αν είναι βόμβα, κάνε νέα τυχαία επιλογή
        board[i][j] = '*';              //Βάλε βόμβα
    }
}   

/*Τοποθέτησε αριθμούς με το πλήθος των γειτονικών βομβών
στα κελιά που δεν έχουν βόμβες (όχι στο περίγραμμα)*/
void putNums(char board[ROWS][COLUMNS], int rows, int columns)
{
    int i, j, k, l;
    char n;                                     //Πλήθος γειτονικών βομβών σε μορφή char
    int m = 0;                                  //Αρχικοποίηση μετρητή βομβών
    for(i=1; i<(rows-1); i++)                   //Για κάθε εσωτερικό κελί
        {
        for(j=1; j<(columns-1); j++)
            if(board[i][j] != '*')              //Αν δεν είναι βόμβα
                for(k=(i-1); k<i+2; k++)        //Έλεγξε τα γειτονικά κελιά
                    for(l=(j-1); l<j+2; l++)    
                        if(board[k][l] = '*')   //Για καθένα που είναι βόμβα
                            m++;                //Αύξησε τον μετρητή βομβών κατά 1
        char n = (char)m;                       //casting από int σε char για το πλήθος γειτονικών βομβών
        board[i][j] = 'm';                      //Δώσε στο κελί την τιμή του μετρητή βομβών
        }
}

//Καταχώρισε περίγραμμα πίστας
void putBorder(char board[ROWS][COLUMNS], int rows, int columns)
{
    int i, j;
    if(i==0 || i==rows+1)
        board[i][j] = '-';
    if(j==0 || j==columns+1)
        board[i][j] = '|';
}

//Τύπωσε τελική πίστα
void printBoard(char board[ROWS][COLUMNS], int rows, int columns)
{
    int i,j;
    for(i=0; i<rows+1; i++)
    {
        printf("\n");
        for(j=0; j<columns+1; j++)
        {
            printf("%c", board[i][j]);
        }
    }
    printf("\n");
}

1 个答案:

答案 0 :(得分:1)

没有编译器警告?为什么不呢?

函数putBorder使用未初始化的变量 ij

void putBorder(char board[ROWS][COLUMNS], int rows, int columns)
{
    int i, j;
    if(i==0 || i==rows+1)
        board[i][j] = '-';
    if(j==0 || j==columns+1)
        board[i][j] = '|';
}

该功能似乎缺少一些循环,如功能printBoard所示。

void putBorder(char board[ROWS][COLUMNS], int rows, int columns)
{
    int i, j;
    for(i=0; i<rows+1; i++)
    {
        for(j=0; j<columns+1; j++)
        {
            if(i==0 || i==rows+1)
                board[i][j] = '-';
            if(j==0 || j==columns+1)
                board[i][j] = '|';
        }
    }
}

但是,复制了这些循环之后,其上限似乎偏离了1。所以我建议

i<rows+2
j<columns+2
在这两个功能中,

etc都允许全面边框。