Search code examples
cstringstructcharactergarbage

C - garbage characters even with null terminator, structures


So as part of a school assignment I have to create an application to handle the input of various fields using a structure. defined outside of main as following

typedef struct stud {
    struct number {
        int studNum;
    } number;
    struct name {
        char firstName[NAME_SIZE];
        char lastName[NAME_SIZE];
    } name;
    struct cellNum {
        int areaCode;
        int prefix;
        int suffix;
    } cellNum;
    struct courses {
        struct fall {
            char className[NAME_SIZE];
            float mark;
        } fall;
        struct winter {
            char className[NAME_SIZE];
            float mark;
        } winter;
    } courses;
} stud;

NAME_SIZE is defined as 30

I access the struct as following

stud studArray[100]; // max 100 students
stud *studPtr;

for (int i = 0; i < studCount; i++) {
    studPtr = &studArray[i];
    initializeStrings(studPtr[i]);
    getNum(studPtr[i]);
    getName(studPtr[i]);
    getCell(studPtr[i]);
    getCourses(studPtr[i]);
}

initializeStrings is where I add the null terminator's

void initializeStrings(stud student) {
    student.name.firstName[NAME_SIZE - 1] = '\0'; 
    student.name.lastName[NAME_SIZE -1] = '\0';
    student.courses.fall.className[NAME_SIZE -1] = '\0';
    student.courses.winter.className[NAME_SIZE -1] = '\0';
}

This is now where the problem occurs: in any of my various functions, when I try and access any of the information I write to my string, I get an output of garbage characters that look like a sideways T, but only if i access the data in a different function.

Example: this is the code to get 2 courses and marks

void getCourses(stud student) {
    getchar();
    printf("\n%s", "Enter Course name - Fall 2016: ");
    fgets(student.courses.fall.className, NAME_SIZE - 1, stdin);
    fflush(stdin); // suggested by my prof to fix the issue, did nothing

    printf("\n%s%s%s", "Enter mark received for ", student.courses.fall.className, ": ");
    scanf("%f", &student.courses.fall.mark);

    getchar();
    printf("\n%s", "Enter Course name - Winter 2017: ");
    fgets(student.courses.winter.className, NAME_SIZE - 1, stdin);

    printf("\n%s%s%s", "Enter mark received for ", student.courses.winter.className, ": ");
    scanf("%f", &student.courses.winter.mark);
}

If I enter helloWorld as a course name, the system correctly prints enter mark received for helloWorld

but when I try and print the data from my print function:

void printData(stud student) {
// various other values (none of which work)
printf("\t%s\t%s\t%f\n", "Fall2016", student.courses.fall.className, student.courses.fall.mark);
}

I get garbage data output ( image )

Any help/code criticism welcome

EDIT: Thank you Eddiem, and everyone else, you pointed me in the right direction.


Solution

  • This code doesn't really make sense. First, why not pass stud* pointers to each of the functions you're calling below? Regardless, the way you have it here, you're initializing studPtr to point to a particular element in the studArray array, but then still indexing i into that pointer. You could probably pass studPtr[0], but that's just weird.

    Original code:

    stud studArray[100]; // max 100 students
    stud *studPtr;
    
    for (int i = 0; i < studCount; i++) {
        studPtr = &studArray[i];
        initializeStrings(studPtr[i]);
        getNum(studPtr[i]);
        getName(studPtr[i]);
        getCell(studPtr[i]);
        getCourses(studPtr[i]);
    }
    

    I would suggest modifications like the following:

    void initializeStrings(stud *student) {
        student->name.firstName[NAME_SIZE - 1] = '\0'; 
        student->name.lastName[NAME_SIZE -1] = '\0';
        student->courses.fall.className[NAME_SIZE -1] = '\0';
        student->courses.winter.className[NAME_SIZE -1] = '\0';
    }
    

    These modifications would need to be made to each if the functions that currently take a stud parameter. Then, change your loop initialization to:

    for (int i = 0; i < studCount; i++) {
        initializeStrings(&studArray[i]);
        getNum(&studArray[i]);
        getName(&studArray[i]);
        getCell(&studArray[i]);
        getCourses(&studArray[i]);
    }