Issues with printing structs in C - arrays

I'm incredibly new to this and have a school assignment I have to write a gradebook program that uses a custom struct to hold student IDs and grades. I have been trying unsuccessfully for days to figure out why it will not print properly, or when it does print (after a lot of shifting things around) it only prints the second set of input.
The gradebook.h section is the custom structure.
// gradebook.h
struct gradeID
{
int id;
char grades[25];
};
// Gradebook.h is a header file to define
// a global structure.
#include "gradebook.h"
#include <stdio.h>
#include <stdlib.h>
void sort(struct gradeID *, int);
int main(void)
{
// Variables and structure definitions
int ctr;
char contInput;
int i;
struct gradeID grade;
struct gradeID *identifier;
int *temps;
// Allocates 10 integers worth of memory for the program to use.
// If there is not enough memory, the program will print an error
// statement and terminate the program.
temps = (int *) malloc(10 * sizeof(int));
if (temps == 0)
{
printf("Not enough memory!\n");
exit(1);
}
// Prints basic instructions for the program
printf("\t\tGradebook Recorder\n");
printf("Input student IDs and grades.\n");
printf("These will be sorted by ID and printed.\n");
/* Creates a for loop that will continue until the program
hits the designated number of array elements. For the sake
of expediency, I have set this amount to 10, but it can be
changed as necessary.*/
for(i = 0; i < 10; i++)
{
printf("Input student ID:\n");
scanf(" %d", &grade.id);
printf("Input grade:\n");
scanf(" %s", grade.grades);
// This allows early exit of the program
printf("Do you have more grades to enter?\n");
printf("Y/N\n");
scanf(" %c", &contInput);
if(contInput == 'N' || contInput == 'n')
{
printf("Finalizing and printing input-\n\n");
break;
}
ctr++;
}
printf("Grades Sorted by Student ID:\n\n");
printf("\tStudent ID: Student Grade: \n");
for(i = 0; i < ctr; i++)
{
printf("\t%d", grade.id );
printf("\t%s", grade.grades);
}
identifier[i] = grade;
return(0);
free(temps);
}
void sort(struct gradeID identifier[], int counter)
{
int inner;
int outer;
struct gradeID temp;
// Loops for sorting
for(outer = 0; outer < counter - 1; ++outer)
{
for(inner = outer + 1; inner < counter; ++inner)
{
if(identifier[inner].id < identifier[outer].id)
{
temp = identifier[inner];
identifier[inner] = identifier[outer];
identifier[outer] = temp;
}
}
}
return;
}

The pointer identifier is uninitialized
struct gradeID *identifier;
So this statement
identifier[i] = grade;
independent on the value of i invokes undefined behavior.
In this for loop
for(i = 0; i < 10; i++)
{
printf("Input student ID:\n");
scanf(" %d", &grade.id);
printf("Input grade:\n");
scanf(" %s", grade.grades);
// This allows early exit of the program
printf("Do you have more grades to enter?\n");
printf("Y/N\n");
scanf(" %c", &contInput);
if(contInput == 'N' || contInput == 'n')
{
printf("Finalizing and printing input-\n\n");
break;
}
ctr++;
}
you are entering new data in the same object grade of the structure type. So the new data overrides the previous data stored in the object.
Moreover the variable ctr was not initialized
int ctr;
So this statement in the above for loop
ctr++;
also invokes undefined behavior.
The variable temps that points to a dynamically allocated array
temps = (int *) malloc(10 * sizeof(int));
is not used.
This statement
free(temps);
never gets the control because before it there is the return statement
return(0);
free(temps);
What you need is to define an array of the type struct gradeID as for example
struct gradeID grades[10];
and fill it with values.

Related

How to delete a value in a struct?

I am trying to delete a "user" from the struct on my code.
For example, this is the struct I have:
struct clients {
char name[30];
int year;
float amount;
};
And this is the two outputs I have:
Name: Victor
Birth Year: 1998
Amount: 1000.00
Name: John
Birth Year: 1996
Amount: 1500.00
What I want to do is to delete John and all his information from my struct.
I am trying to learn dynamic memmory allocation, so I used this command:
clt = (struct clients*) malloc(n * sizeof(struct clients));
In my case I wish to write a command on case 3 that delete john from the struct, but I really can't figure out how to do that, I guess maybe using realloc? But I didn't even get close to write something it would work.
Here is my entire code so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct clients {
char name[30];
int year;
float amount;
};
int main() {
struct clients *clt;
int option, n, d = 0;
char name[30];
printf("Welcome, Choose an option to begin:");
do {
printf("\n1 - Create a new list;\n");
printf("2 - Find a person in the list;\n");
printf("3 - Delete a person from the list.\n");
printf("4 - End the program.\n");
scanf("%d", &option);
switch (option) {
case 1:
printf("\nType how many clients you want to register:");
scanf("%d", &n);
// allocating memory for n numbers of struct person
clt = (struct clients*) malloc(n * sizeof(struct clients));
for (int i = 0; i < n; i++) {
printf("Type the name and the birth year:");
// To access members of 1st struct person,
scanf("%s %d", (clt + i)->name, &(clt + i)->year);
printf("\nType the amount:");
scanf("%f", &(clt + i)->amount);
}
break;
case 2:
printf("Type the name you want to find:");
scanf("%s", name);
for (int i = 0; i < n; i++) {
if (strcmp(&clt[i].name, name) == 0) {
printf("\nThats the name:");
printf("\nName: %s\n", (clt + i)->name);
printf("Birth Year: %d\n", (clt + i)->year);
printf("Amount: %.2f\n", (clt + i)->amount);
d++;
}
}
if (d == 0)
printf("This name doesn't exist\n");
break;
case 3:
break;
case 4:
break;
}
} while (option != 4);
return 0;
}
You need to discard the element from its location in the list by moving the contents in the remainder of the list up , and overwriting the target element.
for(int i = 0; i < n; i++) {
if (strcmp(&clt[i].name, name)==0)
{
printf("\nThats the name:");
printf("\nName: %s\n", (clt+i)->name);
printf("Birth Year: %d\n", (clt+i)->year);
printf("Amount: %.2f\n", (clt+i)->amount);
d++; // This seems to be your sentinel value?
}
if ( 1 == d && i+1 != n ) // if the sentinel is set, but we're not off the end of the list yet
{
memcpy(clt+i, clt+i+1, sizeof( struct clients ));
}
}
n--; // reduce the list length
You could do this in one memmove call if you prefer. As #Neil says in the comments, memmove is tolerant of overlapping source and destination.
if ( 1 == d && i != n-1 ) // if the sentinel is set, but we're not off the end of the list yet
{
memmove(clt+i, clt+i+1, (n-i-1) * sizeof( struct clients ));
break; // break for i
}
You are describing almost a dynamic array such as C++'s std::vector. It is static, but it could be a dynamic array without that much extra work. You could create a container, and split n into the container's capacity and size.
struct clients_array {
size_t size, capacity;
struct clients *data;
};
Instead of having multiple pointers, one could create a struct clients_array for each list. Sample code to deal with the struct clients_array.
#include <inttypes.h>
#include <assert.h>
#include <errno.h>
/** `a` constructor with `n` spots. Returns true or false depending on whether
it could be constructed. */
static int clients_array_reserve(struct clients_array *const a,
const size_t n) {
assert(a && n);
if(n > SIZE_MAX / sizeof *a->data) return errno = ERANGE, 0;
if(!(a->data = malloc(sizeof *a->data * n))) return 0;
a->capacity = n;
a->size = 0;
return 1;
}
/** `a` destructor; call this when `a` has been successfully constructed. */
static void clients_array_(struct clients_array *const a)
{ if(a) { free(a->data); a->data = 0; a->capacity = a->size = 0; } }
/** Extract a new uninitialized entry out of constructed `a`. Returns null if
there is no more space. */
static struct clients *clients_array_new(struct clients_array *const a) {
assert(a);
return a->capacity > a->size ? a->data + a->size++ : 0;
}
/** Remove index `rm` from `a`. */
static void clients_array_delete(struct clients_array *const a,
const size_t rm) {
assert(a && rm < a->size);
memmove(a->data + rm, a->data + rm + 1,
sizeof *a->data * (a->size - rm - 1));
a->size--;
}
Then one can have different, independent arrays at once. If you want to update the code, say to allow realloc to increase the size of the object, you only need to modify the container.

Nested structures and dynamic memory allocation

I am currently learning C and trying to create an app that allows students to input their name, address, student id and any subject id they have while at university (yes this is a task part of foundations of tech course). Basically the following code tries to create an array of students (that is unlimited in size) by using dynamic allocating memory. Further a student can have unlimited amounts of subjects (that is nested within the student subject and is dynamically allocated)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main()
{
typedef struct {
char subjectID[10];
char subjectName[10];
float grades;
}subject;
typedef struct {
char name[10];
int id;
struct subject *enrol;
char address[100];
int status;
int totalSubject;
}student; // This structure is to act like an unlimited list of students
int option=0, q=0, j=0, k=0, p=0, delete=0, position=0;
int count=0; // keeps the count of numbers added
student * studentAddress;
studentAddress = NULL; //Init structure
studentAddress->enrol = NULL; // Init nested structure
int flag = 0; //variable to indicate whether the number to delete is found or not
while (1) // Life cycle of the app
{
printf("1 - Add new student\n");
printf("2 - Display all students\n");
printf("3 - Delete student by id \n");
printf("4 - Delete student by name \n");
printf("5 - Quit\n");
scanf("%d",&option);
switch (option)
{
case 1: studentAddress = realloc(studentAddress, sizeof(student)*(count+1)); //using realloc memory is requested for the new number
printf("Enter your name\n");
fflush(stdin);
gets(studentAddress[count].name);
fflush(stdin);
printf("Enter your id\n");
scanf("%d", &studentAddress[count].id);
printf("Enter your address\n");
fflush(stdin);
gets(studentAddress[count].address);
fflush(stdin);
int subjectCounter = 0;
subjectCounter = 0;
char subjectContinue[10];
for (p = 0; p < subjectCounter; p++)
{
studentAddress[count].enrol = (struct subject *)realloc(studentAddress[count].enrol, (sizeof(subject)*(subjectCounter+1)));
// studentAddress[count].enrol[subjectCounter] = (struct subject *)realloc(sizeof(subject)*(subjectCounter+1));
// Above is teacher paste
printf("What is the id of your subject %d\n", (subjectCounter+1));
fflush(stdin);
gets(studentAddress[count].enrol[subjectCounter].subjectID);
fflush(stdin);
printf("Would you like to add another subject id\n");
fflush(stdin);
gets(subjectContinue);
fflush(stdin);
if (strcmp(subjectContinue, "Y") == 0)
{
subjectCounter++;
}
studentAddress[count].totalSubject = subjectCounter;
}
count++;
printf("\n");
break;
case 2:
for (j=0; j<count; j++)
{
if(studentAddress[j].status != 0)
printf("%s\n %d\n %s\n", studentAddress[j].name, studentAddress[j].id, studentAddress[j].address);
for (q = 0; q < studentAddress[count].totalSubject; q++)
{
printf("%s", studentAddress[j].enrol[q].subjectID);
}
}
printf("\n");
break;
case 3: k=count;
flag=0;
printf("Type the id of the person record you want to delete\n");
scanf("%d", &delete);
for (j=0; j < count; j++)
{
if (delete == studentAddress[j].id)
{
strcpy(studentAddress[j].name, " ");
strcpy(studentAddress[j].address, " ");
studentAddress[j].id = 0;
studentAddress[j].status = 0;
flag = 1;
}
}
if(flag==0)
printf("id not in the list ...\n");
else
printf("Deletion successful ...\n");
printf("\n");
break;
case 4:
flag=0;
char deletChar[100];
printf("Type the name of the person record you want to delete\n");
fflush(stdin);
gets(deletChar);
fflush(stdin);
for (j=0; j < count; j++)
{
if (strcmp(deletChar, studentAddress[j].name)==0)
{
flag = 1;
strcpy(studentAddress[j].name, " ");
strcpy(studentAddress[j].address, " ");
studentAddress[j].id = 0;
studentAddress[j].status = 0;
flag = 1;
}
}
if(flag==0)
printf("name not in the list ...\n");
else
printf("Deletion successful ...\n");
printf("\n");
break;
return 0;
case 5:
return 0;
}
}
return 0;
}
I try running this code and get the error on line 68 and similar on line 95
subscript of pointer to incomplete type 'struct subject'
gets(studentAddress[count].enrol[subjectCounter].subjectID);
plus I get this note (from the compiler) below the error
forward declaration of 'struct subject' struct subject *enrol;
My tutor and lecture have both tried helping me, but they have had no success. They are like most of my code looks correct, but it will not work. Sorry I am new to stack overflow so if you want me to add more information please let me know.
The easiest way to solve this is to create a function.
struct student* allocate_student() {
struct subject* new_subject = allocate_subject();
struct student* new_struct = malloc(sizeof(struct student));
// initialize all fields, which will eventually include
new_struct->enrol = new_subject;
return new_struct;
}
This code fails to check for any error conditions. You should add that. In addition, allocate_subject() is also not defined. Considering the offered example, odds are good you can figure out how to write allocate_subject().
If you add in parameters, allocate_student() might be a bad method name. With enough parameters to construct any student, you might want to call it construct_student(...)

Realloc to structure in c

i have a problem with my realloc in the func add order its crash every time
someone can help me here
typedef struct
{
char carname[30]; //car names
int price; //the price of the car
}Vehicle;
typedef struct {
int number; // מספר הזמנה
char *name; // שם המזמין
char ID[10]; // מספר זהות שלו
int number_vehicles; // מספר הרכבים בהזמנה
Vehicle * list;
int sum_order;
}Order;
Order * add_orders(Order * firma, int * ordersize)// adding one more order
{
int i, j;
char temp[80];
int newstart; // because we need to add one more order we need new start and it will be the old size of the number of orders
newstart = *ordersize; //we just did it
(*ordersize)++; // now we have new size +1 for the one more order
for (i = newstart; i < *ordersize; i++) //same as the input function but this one start and finish from the new start and finish
{
printf("enter the ID of order number: %d\n", i + 1);
scanf("%d", &firma[i].number);
while (getchar() != '\n');
printf("enter the name of the client:\n");
gets(temp);
firma[i].name = (char*)malloc(strlen(temp) + 1 * sizeof(char));
if (!firma[i].name)
{
printf("error\n");
return 0;
}
strcpy(firma[i].name, temp);
printf("enter the ID of client (length can only be 10):\n");
gets(firma[i].ID);
printf("enter how many vehicles you want in this order\n");
scanf("%d", &firma[i].number_vehicles);
firma[i].list = (Vehicle*)malloc(firma[i].number_vehicles * sizeof(Vehicle));
if (!firma[i].list)
{
printf("error\n");
return 0;
}
for (j = 0; j < firma[i].number_vehicles; j++)
{
while (getchar() != '\n');
printf("enter the name of the vehicle number %d (only 30 chars):\n", j + 1);
gets(firma[i].list[j].carname);
printf("enter the price of the vehicle\n");
scanf("%d", &firma[i].list[j].price);
}
}
firma = (Order*)realloc(firma, (*ordersize * sizeof(Order))); //after we added the new order we do realloce for the new size for the struct
if (!firma)//if failed
{
printf("error\n");
return 0;
}
}
int main()
{
int i, j;
char temp[80];
char *str = NULL;
int num, x, y;
int number;
int ordersize;
int exit1 = 0;
int exit2 = 0;
int exit3 = 0;
int flag = 0;
int choose;
Order *data = NULL; //pointer to the struct Order
printf("\nenter how many orders you want\n");
scanf("%d", &ordersize); //enter size of orders
data = (Order*)malloc(ordersize * sizeof(Order));//we allocte memory for the struct Order with pointer data
add_orders(data, &ordersize); //send it
return 0;
}
i have a problem with my realloc in the func add order its crash every time
someone can help me here
i have a problem with my realloc in the func add order its crash every time
someone can help me here
i have a problem with my realloc in the func add order its crash every time
someone can help me here
You access out of bound for firma.
data = (Order*)malloc(ordersize * sizeof(Order));//we allocte memory for the struct Order with pointer data
add_orders(data, &ordersize); //send it
As you allocated memory of size orderSize and you access firma[newstart].
newstart = *ordersize; //we just did it
(*ordersize)++; // now we have new size +1 for the one more order
for (i = newstart; i < *ordersize; i++) //same as the input function but this one start and finish from the new start and finish
{
printf("enter the ID of order number: %d\n", i + 1);
scanf("%d", &firma[i].number);
while (getchar() != '\n');
.....
}
Thus first allocate more memory and access.
newstart = *ordersize; //we just did it
(*ordersize)++; // now we have new size +1 for the one more order
firma = (Order*)realloc(firma, (*ordersize * sizeof(Order))); //after we added the new order we do realloce for the new size for the struct
if (!firma)//if failed
{
printf("error\n");
return 0;
}
for (i = newstart; i < *ordersize; i++) //same as the input function but this one start and finish from the new start and finish
{
printf("enter the ID of order number: %d\n", i + 1);
scanf("%d", &firma[i].number);
while (getchar() != '\n');
.....
}
Note:: firma is local variable and allocating memory using realloc
in addOrder function has no effect on data variable in main
function. You may need to pass data using reference or return
updated value from function and assign it to data.

Proper use of structures and pointers

I have to declare a vector with the "struct" type which, for every n students, it creates a value for the group that student belongs to (which is like a counter), their names and their grades.
The program has to output the name of the students with the highest grade found in these groups. I have to allocate the vector on the heap (I only know the theoretical explanation for heap, but I have no idea how to apply it) and I have to go through the vector using pointers.
For example if I give n the value 4, there will be 4 students and the program will output the maximum grade together with their names as shown here.
This will output Ana 10 and Eva 10.
I gave it a try, but I have no idea how to expand it or fix it so I appreciate all the help I can get with explanations if possible on the practical application of heap and pointers in this type of problem.
#include <stdio.h>
#include <stdlib.h>
struct students {
int group;
char name[20];
int grade;
};
int main()
{
int v[100], n, i;
scanf("%d", n);
for (i = 0; i < n; i++) {
v[i].group = i;
scanf("%s", v[i].name);
scanf("%d", v[i].grade);
}
for (i = 0; i < n; i++) {
printf("%d", v[i].group);
printf("%s", v[i].name);
printf("%d", v[i].grade);
}
return 0;
}
Here I was just trying to create the vector, nothing works though..
It appears, int v[100]; is not quite what you want. Remove that.
You can follow either of two ways.
Use a VLA. After scanning the value of n from user, define the array like struct students v[n]; and carry on.
Define a fixed size array, like struct students v[100];, and use the size to limit the loop conditions.
That said,
scanf("%d", n); should be scanf("%d", &n);, as %d expects a pointer to integer type argument for scanf(). Same goes for other cases, too.
scanf("%s", v[i].name); should better be scanf("%19s", v[i].name); to avoid the possibility of buffer overflow by overly-long inputs.
Even though you are asking for the number of students (groups) using scanf, you hardcoded the upper bound of this value using v[100]. So, I passed your input variable n (the number of students) to malloc in order to allocate the space you need for creating an array of n students.
Also, I used qsort to sort the input array v where the last element would be the max value. Here qsort accepts an array of structs and deference the pointers passed to the comp function to calculate the difference of the comparison.
Finally, I printed the sorted array of structs in the last loop.
#include <stdio.h>
#include <stdlib.h>
struct students {
int group;
char name[20];
int grade;
};
int comp(const void *a, const void *b)
{
return ((((struct students *)a)->grade > ((struct students *)b)->grade) -
(((struct students *)a)->grade < ((struct students *)b)->grade));
}
int main()
{
int n;
printf("Enter number of groups: ");
scanf("%d", &n);
printf("\n");
struct students *v = malloc(n * sizeof(struct students));
int i;
for(i = 0; i < n; i++)
{
v[i].group = i;
printf("\nName: ");
scanf("%s", v[i].name);
printf("Grade: ");
scanf("%d", &v[i].grade);
}
qsort(v, n, sizeof(*v), comp);
for(i = 0; i < n; i++)
{
printf("Group %d, Name %s, grade %d\n", v[i].group, v[i].name, v[i].grade);
}
return (0);
}
You need to replace the standalone array v[100], with an array of structs referencing your structure:
struct students v[100];
However, if you want to use malloc to allocate memory on the heap, you will need to do something like this:
struct students *students = malloc(n * sizeof(struct students));
/* Check void* return pointer from malloc(), just to be safe */
if (students == NULL) {
/* Exit program */
}
and free the requested memory from malloc() at the end, like this:
free(students);
students = NULL;
Additionally, adding to #Sourav Ghosh's answer, it is also good to check the return value of scanf(), especially when dealing with integers.
Instead of simply:
scanf("%d", &n);
A more safe way is this:
if (scanf("%d", &n) != 1) {
/* Exit program */
}
With all this said, your program could look something like this:
#include <stdio.h>
#include <stdlib.h>
#define NAMESTRLEN 20
typedef struct { /* you can use typedef to avoid writing 'struct student' everywhere */
int group;
char name[NAMESTRLEN+1];
int grade;
} student_t;
int
main(void) {
int n, i;
printf("Enter number of students: ");
if (scanf("%d", &n) != 1) {
printf("Invalid input.\n");
exit(EXIT_FAILURE);
}
student_t *students = malloc(n * sizeof(*students));
if (!students) {
printf("Cannot allocate memory for %d structs.\n", n);
exit(EXIT_FAILURE);
}
for (i = 0; i < n; i++) {
students[i].group = i;
printf("Enter student name: ");
scanf("%20s", students[i].name);
printf("Enter students grade: ");
if (scanf("%d", &(students[i].grade)) != 1) {
printf("Invalid grade entered.\n");
exit(EXIT_FAILURE);
}
}
printf("\nStudent Information:\n");
for (i = 0; i < n; i++) {
printf("Group: %d Name: %s Grade: %d\n",
students[i].group,
students[i].name,
students[i].grade);
}
free(students);
students = NULL;
return 0;
}

Expression must have class type error

I'm working on a homework assignment and I've hit a brick wall. I think I have all of the code that I need, I just need to get the program to compile. The object of the assignment is
Create a structure to hold student names and averages. The structure should contain a first name, last name and an integer grade average.
Then:
Write a program that will do the following:
1.) Create an array of pointers to these student structures.
2.) Prompt the user for names and averages.
3.) After you get the student’s information use malloc to provide the memory to store the information.
4.) Place the address of the student, returned by malloc, into the pointer array.
5.) AFTER the user indicates there are no more students:
Search the data entered and find the highest and lowest grade
average.
a)Print the name and grade for the highest grade
b)Print the name and grade for the lowest grade
c)Print the average of all grades entered
Here is my code:
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
#define SIZE 25
int enterStudents (int ePointArray[SIZE]);
void searchData (int *sPointArray, int *sHigh, int *sLow);
int calculateAvg (int, int *avgPointArray);
void printData (int, int *pHigh, int *pLow);
struct student
{
char firstName[20];
char lastName[20];
int average;
};
int main()
{
int pointArray[SIZE], high[3], low[3];
int i = 0, studentCounter, avgGrade;
for (i = 0; i < SIZE; i++)
pointArray[i] = 0;
studentCounter = enterStudents(pointArray);
searchData(pointArray, high, low);
avgGrade = calculateAvg(studentCounter, pointArray);
printData(avgGrade, high, low);
return 0;
}
int enterStudents (int ePointArray[SIZE])
{
char tempFname[20], tempLname[20], yesNo[2] = "y";
int tempAvg, counter = 0;
int *studPtr;
struct student aStud={"\0", "\0", 0};
while( counter < SIZE && strcmp(yesNo, "y")==0)
{
printf(" Enter first name: ");
scanf("%s", tempFname);
printf(" Enter last name: ");
scanf("%s", tempLname);
printf(" Enter grade average:");
scanf("%d", tempAvg);
strcpy(aStud.firstName, tempFname);
strcpy(aStud.lastName, tempLname);
aStud.average = tempAvg;
studPtr = malloc(sizeof(struct student));
ePointArray[counter] = *studPtr;
counter++;
printf("/n");
printf(" Do you have more students? yes or no:");
scanf("%s", yesNo);
}
return counter;
}
void searchData (int sPointArray[SIZE], int sHigh[3], int sLow[3])
{
int searchCounter = 0;
while( searchCounter = 0)
{
if( *sPointArray[searchCounter].average > *sPointArray[searchCounter+1].average)
{
sHigh[0] = &sPointArray[searchCounter].firstName;
sHigh[1] = &sPointArray[searchCounter].lastName;
sHigh[2] = &sPointArray[searchCounter].average;
}
if( *sPointArray[searchCounter].average < *sPointArray[searchCounter+1].average)
{
sLow[0] = &sPointArray[searchCounter].firstName;
sLow[1] = &sPointArray[searchCounter].lastName;
sLow[3] = &sPointArray[searchCounter].average;
}
searchCounter++;
}
}
int calculateAvg( int totalStudents, int avgPointArray[SIZE])
{
int sum = 0;
int avgCounter;
double overallAvg;
for( avgCounter = 0; avgCounter < totalStudents; avgCounter++)
sum = sum + *avgPointArray[avgCounter].average;
overallAvg = sum/totalStudents;
return overallAvg;
}
void printData (int pAverage, int pHigh[3], int pLow[3])
{
printf(" Highest Grade: %s %s %d", pHigh[0], pHigh[1], pHigh[3]);
printf("/n");
printf(" Lowest Grade: %s %s %d", pLow[0], pLow[2], pLow[3]);
printf("/n");
printf(" Average Grade: %d",pAverage);
}
The main chunk of problems come from the searchData function. In the if statements, every occurrence of *sPointArray and &sPointArray is underlined in red and the error reads
"Error: expression must have class type"
The same thing also happens in the calculateAvg function with *avgPointArray in the for loop. I know that the error is a fairly common problem for noobie C programmers (i.e myself) and that it generally has to do with writing the code as a function instead of a statement or something like that, but I can't for the life of me find where I have went wrong. Any help would be highly appreciated. I've been working at this for so long my vision is blurring.
Also, for anyone who solves this in like two seconds and wants proof that I'm a true idiot, there is an error in the enterStudents function where it says StudPtr = malloc(sizeof...). The error shows under the assignment symbol and says
"Error: a value of type "void*" cannot be assigned to an entity of type "int*".
I understand this concept in theory, but some advice for how to fix it would be highly appreciated.
Thank you in advance for any help.
You declare the sPointArray as an array of integers, but use it as an array of structures.

Resources