SCREAM2NIGHT SCREAM2NIGHT - 9 days ago 4
C Question

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

Answer

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]);
}