Using structures in C with user defined functions - c

I had came across a problem that I have tried so many times with different ways but still not able to obtain the required solution please do help me.
PROBLEM: Define a structure to store students’ details. Pass them to a function where the student with HIGHEST CGPA is calculated from a set of 5 students. And display the result.(Here we have to store name, age and CGPA obtained of each student)
Here is my try at the problem:
#include <stdio.h>
void highCGPA(float b,struct detst D[4]);
struct detst
{
int age;
float CGPA;
char name[30];
};
int main()
{
struct detst D[4];
int i;
float h;
for(i=0;i<=4;i++)
{
printf("Enter the name of student %d:\n",i+1);
scanf("%s",&D[i].name);
printf("Enter the age of student %d:\n",i+1);
scanf("%d",&D[i].age);
printf("Enter the CGPA obtined by student %d:\n",i+1);
scanf("%f",&D[i].CGPA);
}
highCGPA(h,D);
}
void highCGPA(float b,struct detst D[4])
{
int i,max;
max = D[0].CGPA;
for(i=0;i<=4;i++)
{
if(D[i].CGPA > max)
{
max = D[i].CGPA;
}
}
printf("Highest CGPA obtained is:\n%f",max);
}

There is more than one problem. You're trying to store the data of 5 students in an array of struct with size 4. So:
struct detst D[5]; // fixed size
int i;
float h;
for(i=0;i<5;i++) { // EDIT (comments suggestion): for loop fix following standard convetions
/* take input */
}
Lastly, if you declare max as an int, you can't try to print it with a format specifier for float. So:
printf("Highest CGPA obtained is: %d\n",max); // format specifier for int is %d (not %f)

There are couple of other problems.
your declaration of funtion highCGPA is above your struct detst definition
you should have got error
error: array type has incomplete element type ‘struct detst’
declare your function after the structure definition.
your max variable is int in the function highCGPA , but you are trying to store a float value in it.

With a sligth change to program functionallity can be improved:
#include <float.h> // FLT_MAX
#include <stdio.h>
struct detst
{
int age;
float CGPA;
char name[30];
};
// Return offset of student with highest CGPA
int highCGPA(struct detst const (*D)[5]); // Using pointer to array
// to avoid degeneration
int main()
{
struct detst D[5];
int i;
for(i = 0; i < 5; i++)
{
printf("Enter the name of student %d:\n", i + 1);
scanf("%29s", D[i].name); // Make sure we don't overwrite the buffer
printf("Enter the age of student %d:\n", i + 1);
scanf("%d", &D[i].age);
printf("Enter the CGPA obtained by student %d:\n", i + 1);
scanf("%f", &D[i].CGPA);
}
int bestStudentOffset = highCGPA(&D); // By asking for best student
// we can obtain a lot more
printf(
"Best student is %d year old %s with\n",
D[bestStudentOffset].age,
D[bestStudentOffset].name);
printf("Highest CGPA obtained is:\n%f\n", D[bestStudentOffset].CGPA);
}
// Return offset of student with highest CGPA
int highCGPA(struct detst const (*D)[5])
{
int i, maxOffset = -1;
float max = -FLT_MAX;
for(i = 0; i < 5; i++)
{
if((*D)[i].CGPA > max)
{
max = (*D)[i].CGPA;
maxOffset = i;
}
}
return maxOffset;
}

Related

What this error mean : expression must have pointer to object type but it has type struct add_stock in c

#include <stdio.h>
int i, n;
struct add_stock
{
char fullname[30];
int stocks;
char com_name[30];
int shares;
float price;
float total;
int totalmoney;
} add;
int main()
{
printf("Enter full name : ");
scanf(" %[^\n]s", add.fullname);
printf("Enter the no. of stocks you want to purchased : ");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("Enter the name of the company : ");
scanf(" %[^\n]s", add[i].com_name);
printf("Enter the no. of shares you want to purchased : ");
scanf("%d", &add[i].shares);
printf("Enter the price of each share : ");
scanf("%f", &add[i].price);
add.total = add.shares * add.price;
printf("Toatl money invested in this stock : ");
scanf("%f", &add[i].total);
}
printf("Total money invested : ");
scanf("%d", add.totalmoney);
return 0;
}
In question it's add_stock , not add stock , i write like this becoz it's not accepting question.
So, i get error for "add" saying subscripted value is neither array nor pointer nor vector.
To declare an array of strucuture, you need to define the variable as below,
struct add_stock
{
char fullname[30];
int stocks;
char com_name[30];
int shares;
float price;
float total;
int totalmoney;
} add[20];
this makes the add as an array of add_stock elements.
then you can access it as, add[0].total, add[1].price and so on.
If you want to declare an array that need to be having dynamic number of elements, you can do so as below.
struct add_stock* arStock;
//allocate memory to hold 10 elements
arStock = (add_stock*)malloc( 10 * sizeof(struct add_stock));
arStock[0]->total=10; //access it with ->, instead of .

confusion comparing structures

the question is to calculate the average of each student separately and then show the id and the average of rank one student. how to compare members of structure
#include<stdio.h>
typedef struct student
{
int id;
float math,physics;
float av;
}std;
int main()
{
int i;
std p[5];
for(i=0;i<5;i++)
{
printf("enter student(%d) id: ",i+1);
scanf("%d",&p[i].id);
printf("grade of math over 100: ");
scanf("%f",&p[i].math);
printf("grade of physics over 100: ");
scanf("%f",&p[i].physics);
printf("average=%.3f\n\n",(p[i].math+p[i].physics)/2);
}
}
To compare on element with another you would take either
p[index]->av {comparaision} p[index]->av
Example p[0]->av > p[1]->av
Don't forget printf("average=%.3f\n\n",(p[i].math+p[i].physics)/2); will print you the result of av but will not save it in p. Save it in p[index].av to be able to do comparaisons.
Then afterward just do a loop where you compare each of them and save their id in an array. The array should be based on a decreasing average with the matching id. Then just print the array and you will be good to go.
#include<stdio.h>
typedef struct studentd
{ int id;
float math,physics;
float av;
} std;
int main()
{
int i,a;
std p[5];
for(i=0; i<5; i++)
{
printf("student(%d) id: ",i+1);
scanf("%d",&p[i].id);
printf("grade of math over 100: ");
scanf("%f",&p[i].math);
printf("grade of physics over 100: ");
scanf("%f",&p[i].physics);
printf("average=%.3f\n\n",p[i].av=(p[i].math+p[i].physics)/2);
}
int max=p[0].av;
for(i=0; i<5; i++)
{
if(p[i].av<=p[i+1].av)
{
max=p[i].av;
}
}
printf("the highest average is for student: %d ",p[i].id);
return 0;
}
/*END*/
/now this is the updated code my problem is how to link the id of student to the max to show the id of student whi got the highest mark/
Well one of two things,
Either add an integer to track the index of the structure containing the max,
Or instead of
max =p[i].avg
Use max = p[i]
Of course let max be a struct not float or int

Building a struct with a function

Hello i'm trying to build a function to search a car for a client by client demand.
The structure contains: model,year,price.
the client is asked to enter his demands and then the code calls a function that check if there is a car in the structure that is suitable for him.
I get error for "access violation reading error"
thanks!
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#define SIZE 10
typedef struct
{
char model[10];
float price;
int year;
}car;
void findCar(car *arr[], int minYear, float maxPrice, char modelWanted, int carAmount);
int main()
{
int carAmount;
car* arr;
puts("How many cars?");
scanf("%d", &carAmount);
arr = (car*)malloc(carAmount * sizeof(car));
if (arr == NULL)
return -1;
for (int i = 0; i < carAmount; i++)
{
puts("Enter car details, Model, Price,Year");
scanf("%s%f%d",arr[i].model,&arr[i].price,&arr[i].year);
}
char modelWanted[SIZE];
float maxPrice;
int minYear;
puts("Enter wanted model,maximum price and minimum year!");
scanf("%s%f%d", modelWanted, &maxPrice, &minYear);
for (int i = 0; i < carAmount; i++)
printf("Model is: %s, Price is: %.2f, Year is: %d\n", arr[i].model, arr[i].price, arr[i].year);
findCar(&arr, minYear, maxPrice, modelWanted, carAmount);
free(arr);
return 1;
}
void findCar(car *arr[], int minYear, float maxPrice, char modelWanted,int carAmount)
{
int i, counter = 0;
for (i = 0; i < carAmount; i++)
if (((strcmp(arr[i]->model, modelWanted)) == 0) && (arr[i]->year >= minYear) && (arr[i]->price <= maxPrice))
{
printf("Model is: %s, Price is: %.2f, Year is: %d\n", arr[i]->model, arr[i]->price, arr[i]->year);
++counter;
}
printf("We found %d cars for you!", counter);
}
You are passing pointer to array of struct
car *arr[]
so instead of accessing elements by arr[i]->model like you do, you should access them using (*arr)[i].model. The method you uses is for accessing the array of pointers to struct element, but you have pointer to array of struct.
Of course already commented char instead of char* will also cause run time error, but you should have received compiler warning for this.

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.

2 questions on typedef struct and averages on grades. Am I doing it correctly In C?

I need help on two questions, Its not homework but its to study for an exam. I need to have these questions because i was allowed 1 full page of notes for the exam. If you could help me these two simple questions for me that would be great. Here are the questions:
"Write a function called getGrades. The function that repeatedly prompts the user for positive integers until the user enters a negative value to stop. The function should return the average of these grades and the highest grade."
"Write a function called Get_Info that takes a pointer to a student structure, (that has three fields: char array called name, an int id, and a double gpa) as its only argument. The function prompts the user for the required information to fill the structure and stores it in the appropriate fields."
What I have so far, Let me know if they are correct and if i need to add anything.
1.
double getGrades() {
double average;
double i;
For(i=1 ; i<i; i++)
{
printf("Enter Grade1:\n");
scanf("%lf", &i);
}
if (i<0)
{
(double) average == (grade1 + grade2 + grade3) / 3;
return average;
}
}
2.
typedef struct {
int id;
double gpa;
char name[SIZE];
} student;
void Get_Info(student list[], int num) {
int i;
for(i=0; i<num; i++) {
printf("\nName:%s", list[i].name);
printf("\nGPA:%lf", list[i].gpa);
printf("\nID: %d\n", list[i].id);
}
}
On #1: The requirement is that the function accept ints. You are scanning for doubles.
The requirement is "The function should return the average of these grades and the highest grade." You only return one double, when two different outputs are called for.
Your for loop is written as "For" (C is case-sensitive), and is based on the test i<i. When will i ever be less than itself??
Here's my version of it.
double getGrades(int* max)
{
int sum = 0;
int input;
int i = 0;
*max = 0;
printf("Enter Grade #%d:\n", i+1);
scanf("%d", &input);
while (input > 0) {
if (*max < input) {
*max = input;
}
sum = sum + input;
i++;
printf("Enter Grade #%d:\n", i+1);
scanf("%d", &input);
}
return i? ((double)sum / i) : 0;
}
Your #2 is much better than your #1, but still has some errors:
The requirement is that the function takes a pointer to a student struct, NOT an array.
It should then print a series of Prompts, and get a series of answers (just as you did in #1).
This is a sequence of printf/scanf.
And when using scanf, you typically pass the ADDRESS of the variable, using &.
(strings are a exception, however)
Here is my version:
typedef struct {
char name[SIZE];
int id;
double gpa;
} student;
void Get_Info(student* ps) {
printf("Enter Name\n");
scanf("%s", ps->name);
printf("Enter ID:\n");
scanf("%d", &ps->id);
printf("Enter GPA\n");
scanf("%lf", &ps->gpa);
}
Try this. It should seem intuitive enough:
double getGrades() {
double average;
double grade;
double total = 0;
int count = 0;
while (1) {
printf("Enter grade: ");
scanf("%d", &grade);
if (grade < 0) {
if (count == 0) {
average = 0;
break;
}
average = total/count;
break;
}
count++;
total += grade;
}
return average;
}

Resources