mardi 21 juin 2016

C Program Working Fine on Windows, Segmentation Fault on Linux

I'm writting a program in C Language and it works perfect on Windows, but gives me Segmentation Fault when selecting function 3 (settings) in the main menu. Why?

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

#ifdef _WIN32
#define CLEAR "cls"
#else
#define CLEAR "clear"
#endif


char characters[11];
int lines, columns; 
float base_score; 
FILE *fp;

void helloworld(){ 
    printf("Welcome!n");
    printf("Press <ENTER> to continue...");
    while( getchar() != 'n' ) getchar();   
}

int menuMain() { 
    int option;

    printf("MAIN MENUn");
    printf("1 - Playn");
    printf("2 - Rankingn");
    printf("3 - Settingsn");
    printf("4 - Leaven");
    printf("n");
    printf("Choose:");

    scanf("%d", &option);
    while((option!=1)&&(option!=2)&&(option!=3)&&(option!=4)) {
        printf("Invalid selection. Try again please.n");
        printf("Press <ENTER> to continue...n");
        while( getchar() != 'n' );
        getchar();  
        system(CLEAR);
        menuMain();

    }
    return option;
}

void play () {
    printf("Under construction...n");
}

void ranking () {
    printf("Under construction...n");
}


void settings();

typedef enum {
 false = 0,
 true,
} bool;

bool invalidChars() {
    if((strlen(characters)<3)||(strlen(characters)>10)) return true;
    else return false;
}

bool invalidRows() {
    if((lines<3)||(lines>9)) return true;
    else return false;

}

bool invalidCols() {
    if((lines<3)||(lines>9)) return true;
    else return false;
}

bool invalidScoreBase() {
    if((base_score<1)||(base_score>2)) return true;
    else return false;
}

int settingsMain() { 
    int option; 

    printf("SETTINGSn");
    printf("1 - Change characters: %sn", characters);
    printf("2 - Change lines: %dn", lines);
    printf("3 - Change columns: %dn", columns);
    printf("4 - Change base score: %.2fn", base_score);
    printf("5 - Main menun");
    printf("n");
    printf("Choose:");

    scanf("%d", &option);
    if((option!=1)&&(option!=2)&&(option!=3)&&(option!=4)&&(option!=5)) { 
        printf("Invalid selection. Try again please.n");
        printf("Press <ENTER> to continue...");
        while( getchar() != 'n' );
        getchar();  
        system(CLEAR); 
        settings(); 

    }
    return option;
}

void writesettings(FILE *fp) { 
    fprintf(fp, "%sn%dn%dn%fn", characters, lines, columns, base_score);
}

void readsettings() { 
    fp = fopen("EliminaLetras_settings.txt", "r+");
    if (fp == NULL) {
        strcpy(characters, "OZXM");
        lines = 6;
        columns = 9; 
        base_score = 1.5;
        writesettings(fp);
    }
    else {
        fscanf(fp, "%sn%dn%dn%fn", characters, &lines, &columns, &base_score);
        rewind(fp);
        writesettings(fp);
    }
    fclose(fp);
}

void changeChars() {
    char op;
    bool test;
    printf("Insert new characters(min 3, max 10):");
    scanf("%s", characters);
    printf("Confirm? (Y/N)?");
    scanf(" %c", &op);
    getchar();
    if((op == 'Y')||(op == 'y')) {
        test = invalidChars();
        if (test == true) {
            printf("Invalid selection. Try again please.n");
            changeChars();
        }
        else {
            fp = fopen("EliminaLetras_settings.txt", "w+");
            writesettings(fp);
            fclose(fp);
        }
    }
}
void changeRows() {
    char op;
    bool test;
    printf("Insert new number of lines(min 3, max 9):");
    scanf("%d", &lines);
    printf("Confirm? (Y/N)?");
    scanf(" %c", &op);
    getchar();
    if((op == 'Y')||(op == 'y')) {
        test = invalidRows();
        if (test == true) {
            printf("Invalid selection. Try again please.n");
            changeRows();
        }
        else {
            fp = fopen("EliminaLetras_settings.txt", "w+");
            writesettings(fp);
            fclose(fp);
        }
    }
}
void changeCols() {
    char op;
    bool test;
    printf("Insert new number of columns (min 3, max 9):");
    scanf("%d", &columns);
    printf("Confirm (Y/N)?");
    scanf(" %c", &op);
    getchar();
    if((op == 'Y')||(op == 'y')) {
        test = invalidCols();
        if (test == true) {
            printf("Invalid selection. Try again please.n");
            changeCols();
        }
        else {
            fp = fopen("EliminaLetras_settings.txt", "w+");
            writesettings(fp);
            fclose(fp);
        }
    }
}
void changeScoreBase() {
    char op;
    bool test;
    printf("Insert new base score (min 1, max 2):");
    scanf("%f", &base_score);
    printf("Confirm? (Y/N)?");
    scanf(" %c", &op);
    getchar();
    if((op == 'Y')||(op == 'y')) {
        test = invalidScoreBase();
        if (test == true) {
            printf("Invalid selection. Try again please.n");
            changeScoreBase();
        }
        else {
            fp = fopen("EliminaLetras_settings.txt", "w+");
            writesettings(fp);
            fclose(fp);
        }
    }
}

void settings () {  
    int op = 0; 
    readsettings();
    op = settingsMain();
    switch (op) {
        case 1:
            changeChars();
            system(CLEAR);
            settings();
            break;
        case 2:
            changeRows(); 
            system(CLEAR);
            settings();
            break;
        case 3:
            changeCols(); 
            system(CLEAR);
            settings();
            break;
        case 4:
            changeScoreBase();
            system(CLEAR);
            settings();
            break;
        case 5:
            system(CLEAR);
            getchar();
            main ();
            break;  
    }
}


void quit () {
    printf("Goodbye!n");
    printf("Press <ENTER> to continue...");
    while(getchar() != 'n');
    getchar();
}


int main () {
    int op;
    helloworld();
    system(CLEAR);
    op = menuMain();
    switch (op) {
        case 1:
            system(CLEAR);
            play();
            break;
        case 2:
            system(CLEAR);
            ranking();
            break;
        case 3:
            system(CLEAR);
            settings();
            break;
        case 4:
            system(CLEAR);
            quit();
            break;
    }
    return 0;
}

Sorry for the long code, but I really have no clue as to where is my mistake. My best guess is it is either on the "settings" function or main itself. Any help would be greatly appreciated.

Aucun commentaire:

Enregistrer un commentaire