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

struct birthdate {
    int month, day, year;
};

typedef struct {
    char fatherName[30];
    char motherName[30];
} parentage;

typedef struct demigod {
    char firstName[50];
    char lastName[30];
    int age;

    parentage parents;
    struct birthdate birthday;
} halfblood;

void addDemigod(struct demigod *camphalfblood, int i) {
    printf("Enter name: ");
    scanf("%s %s", camphalfblood[i].firstName, camphalfblood[i].lastName);

    printf("Enter birth month: ");
    scanf("%d", &camphalfblood[i].birthday.month);

    printf("Enter birth day: ");
    scanf("%d", &camphalfblood[i].birthday.day);

    printf("Enter birth year: ");
    scanf("%d", &camphalfblood[i].birthday.year);

    camphalfblood[i].age = 2020 - camphalfblood[i].birthday.year;

    printf("Enter mother's name: ");
    scanf("%s", camphalfblood[i].parents.motherName);

    printf("Enter father's name: ");
    scanf("%s", camphalfblood[i].parents.fatherName);
}

void printAll (struct demigod *camphalfblood, int index) {
    for (int i = 0; i < index; i++) {
        printf("\nNAME : %s %s\n", camphalfblood[i].firstName, camphalfblood[i].lastName);
        printf("BIRTHDAY: %d-%d-%d\n", camphalfblood[i].birthday.month, camphalfblood[i].birthday.day, camphalfblood[i].birthday.year);
        printf("AGE: %d\n", camphalfblood[i].age);
        printf("PARENTS: %s and %s\n\n", camphalfblood[i].parents.motherName, camphalfblood[i].parents.fatherName);
    }
}

void editDemigod(struct demigod *camphalfblood, int index) {
    int i;

    for (i = 0; i < index; i++) {
        printf("[%d] %s %s\n", i, camphalfblood[i].firstName, camphalfblood[i].lastName);
    }

    int choice;
    printf("Enter index: "); 
    scanf("%d", &choice);

    printf("Enter new first name: ");
    scanf("%s", camphalfblood[choice].firstName);
    printf("Enter new last name: ");
    scanf("%s", camphalfblood[choice].lastName);
}

int main() {
    struct demigod camphalfblood[20];
    int choice;
    int index = 0;

    while (1) {
        printf("[1] Add Demigod\n");
        printf("[2] Print All Demigods\n");
        printf("[3] Edit Demigod\n");
        printf("[4] Exit\n");

        printf("Enter choice: ");
        scanf("%d", choice);

        if (choice == 1) {
            addDemigod(camphalfblood, index);
            index++;
            printf("Successfully added!\n");
        } else if (choice == 2) {
            printAll(camphalfblood, index);
        } else if (choice == 3) {
            editDemigod(camphalfblood, index);
        } else if (choice == 4) {
            break;
        }
    }
    return 0;
}

Here's my code. There's no error when I compile it but the program somehow stops when after I entered the choice. I don't know where the error is. It just don't run and I don't know why. please help me, I really dont know what happened.

enter image description here

this is the output that I keep seeing, the program just stops there suddenly.

EDIT: I already got it, ampersands made me dumb wtf HAAAHAHAH

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • 2
    Please enable compiler warnings and pay heed to them. Once you do that, you will see a compiler warning on the line `scanf("%d", choice);` since you passed the value of the variable instead of its address. – Spikatrix May 21 '22 at 10:29
  • what part is that? on what function? – User617290653251457439 May 21 '22 at 10:40
  • 1
    The compiler will tell you the line of the warning. Please enable them. (Also, there's only one `scanf("%d", choice);` in your code, so I'm not sure why you can't find it) – Spikatrix May 21 '22 at 10:43
  • @Spikatrix i already figured it out omg, you're right my code is lacking multiple ampersands wtf HAHAHAAHHA thank u so much!! – User617290653251457439 May 21 '22 at 10:48
  • 1
    Uh, not really. You were missing the ampersand on the line I've shown only. For `scanf` with `%s` you should not be using the ampersand. You will get a warning if you do so. – Spikatrix May 21 '22 at 10:52
  • ohh i see, when i added an ampersand on the first scanf on the addDemigod, it didn't prompt an error so i thought thats the problem together with the scanf %d. thank you for explaining! – User617290653251457439 May 21 '22 at 10:58
  • You may want to read this: [Why should I always enable compiler warnings?](https://stackoverflow.com/q/57842756/12149471) – Andreas Wenzel May 21 '22 at 11:28

1 Answers1

2

The error is here: scanf("%d", choice); has undefined behavior because you pass the value of choice instead of its address. This probably causes an invalid memory access resulting in program termination.

The solution is: scanf("%d", &choice)

Note that you should also check the return value of scanf() to detect invalid or missing input.

You should also pass the maximum number of characters for %s to avoid undefined behavior on user input longer than expected.

Here is a modified version of addDemigod() using helper functions:

int flushInput(void) {
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        continue;
    return c;
}

int invalidInput(void) {
    int res = 1;
    printf("invalid input\n");
    if (flushInput() == EOF) {
        printf("unexpected end of file\n");
        return 2;
    } else {
        return 1;
    }
}

int addDemigod(struct demigod *camphalfblood, int i) {
    printf("Enter name: ");
    if (scanf("%49s %29s", camphalfblood[i].firstName, camphalfblood[i].lastName) != 2)
        return invalidInput();

    flushInput();
    printf("Enter birth month: ");
    if (scanf("%d", &camphalfblood[i].birthday.month) != 1)
        return invalidInput();

    flushInput();
    printf("Enter birth day: ");
    if (scanf("%d", &camphalfblood[i].birthday.day) != 1)
        return invalidInput();

    flushInput();
    printf("Enter birth year: ");
    if (scanf("%d", &camphalfblood[i].birthday.year) != 1)
        return invalidInput();

    camphalfblood[i].age = 2020 - camphalfblood[i].birthday.year;

    flushInput();
    printf("Enter mother's name: ");
    if (scanf("%29s", camphalfblood[i].parents.motherName) != 1)
        return invalidInput();

    flushInput();
    printf("Enter father's name: ");
    if (scanf("%29s", camphalfblood[i].parents.fatherName) != 1)
        return invalidInput();

    flushInput();
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189