Why does this array of structures overwrite char * but not int? [duplicate] - c

This question already has answers here:
How to access a local variable from a different function using pointers?
(10 answers)
Closed 1 year ago.
I have written a program which makes use of array of structures in order to maintain a sort of "database" program with different options that can be used to manipulate the "database".
The program has 4 modes of operation, if the user enters:
'i' data can be inserted into the "database".
's' searches the "database" for a part with a part number of a item.
'u' updates something in the database based on the part number of a item.
'p' prints the whole "database".
Here is the code which is made of 3 files:
database.h:
#ifndef DATABASE
#define DATABASE
struct db
{
int part_number;
char *part_name;
int part_quantity;
};
extern struct db database[50];
extern void insert(int i);
extern int search(int i);
extern int update(int i);
extern int print(int i);
#endif
database.c
#include <string.h>
#include <stdio.h>
#include "database.h"
struct db database[50];
void insert(int i)
{
char name_of_part[21], c;
printf("%p\n", &database[i].part_name);
printf("\n");
printf("Enter a part number: ");
scanf("%d", &database[i].part_number);
while((c = getchar()) != '\n' && c != EOF); // flush stdin
printf("Enter a part name: ");
fgets(name_of_part, 20, stdin);
printf("Enter quantity of part: ");
scanf("%d", &database[i].part_quantity);
database[i].part_name = name_of_part;
printf("\n");
}
int search(int i)
{
int input;
printf("\n");
printf("Enter a part number: ");
scanf("%d", &input);
for (int j = 0; j <= i; j++)
{
if (database[j].part_number == input)
{
printf("Part name: %s\n", database[j].part_name);
printf("Quantity on hand: %d\n", database[j].part_quantity);
return 0;
}
}
printf("Part not found.\n");
}
int update(int i)
{
int input, quantity;
printf("\n");
printf("Enter part number: ");
scanf("%d", &input);
for (int j = 0; j <= i; j++)
{
if (database[j].part_number == input)
{
printf("Enter part quantity: ");
scanf("%d", &quantity);
database[j].part_quantity = quantity;
return 0;
}
}
printf("Part number not found.");
}
int print(int i)
{
for (int j = 0; j < i; j++)
{
printf("Part number: %d\n Part name: %s\n Part quantity: %d\n", database[j].part_number, database[j].part_name,database[j].part_quantity);
}
}
main.c
#include <stdio.h>
#include <string.h>
#include "database.h"
int main()
{
int i = 0;
char code;
while (1)
{
printf("Enter a function code: ");
scanf(" %c", &code);
switch (code)
{
case 'i':
insert(i);
i += 1;
break;
case 's':
search(i);
break;
case 'u':
update(i);
break;
case 'p':
print(i);
break;
}
}
return 0;
}
The problem i have is that when i insert into the "database", the name in each structure gets overwritten. for example:
Enter a function code: i
Enter a part number: 111
Enter a part name: 111
Enter quantity of part: 111
Enter a function code: i
Enter a part number: 222
Enter a part name: 222
Enter quantity of part: 222
Enter a function code: p
Part number: 111
Part name: 222
Part quantity: 111
Part number: 222
Part name: 222
Part quantity: 222
Enter a function code:
As you can see first i insert something new in the "database", take note of the "Part name" which is "111".
Next i insert something else into the database
this time the "Part name" is "222".
Lastly i print the whole "database" what i am confused about is why the part name has now overlapped. but why is this? all the other members such as the part_number and part_quantity remain intact in both insert operations so why does char *part_name stay the same ? and how do i fix this ?

You have the part_name member declared as a char * and you assign to it the address of a local array in the insert function. When the function returns, that array goes out of scope and the stored pointer becomes invalid. Subsequently trying to use that pointer triggers undefined behavior.
Change part_name to be an array:
struct db
{
int part_number;
char part_name[21];
int part_quantity;
};
And write directly to that:
printf("Enter a part name: ");
fgets(database[i].part_name, 21, stdin);

The line
database[i].part_name = name_of_part;
is bad. This is assigning a pointer to the non-static local variable. The variable ends its life on returning from the function and dereferencing pointers pointing to that is illegal.
Instaed of this, you have to copy the string. If you system supports strdup(), it can be done like this:
database[i].part_name = strdup(name_of_part);
If strdup() is not supported or you want to stick to the standard, you dan do like this:
database[i].part_name = malloc(strlen(name_of_part) + 1); /* +1 for ther terminating null-character */
if (database[i].part_name != NULL)
{
strcpy(database[i].part_name, name_of_part);
}
Add #include <stdlib.h> to use malloc().

Related

Array of strings concatenating positions

I am programming a registration system using array strings for postal code and home address. I use a constant to determine the postal code limit of just 8 characters.
When the program start the register function, it makes the address and postal code inputs correct, but when I list it, the address appears normal and the postal code of position 1 together with the others below. Why is this happening? I put 8 character positions for the postal code and it increases by placing the second one as well.
My program:
#include <stdio.h>
#define LIMIT_POSTAL 8
#define LIMIT_REGISTER 5
#define LIMIT_ADDRESS 20
char postal_c[LIMIT_REGISTER][LIMIT_POSTAL], address[LIMIT_REGISTER][LIMIT_ADDRESS];
int line;
void reg()
{
int op;
do
{
printf("Address: ");
scanf("%s", &address[line]);
printf("Postal code: ");
scanf("%s", &postal_c[line]);
op = -1;
printf("1 - Continue\nAny number - Exit\n");
scanf("%d", &op);
line++;
} while(op == 1);
}
int main()
{
int i;
reg();
for(i = 0; i < line; i++)
{
printf("Address: %s\n", address[i]);
printf("Postal: %s\n", postal_c[i]);
}
return 0;
}
Output:
Address: foo
Postal code: 11111111
1 - Continue
Any number - Exit
1
Address: foo2
Postal code: 22222222
1 - Continue
Any number - Exit
0
Address: foo
Postal: 1111111122222222
Address: foo2
Postal: 22222222
In your code probably:
#include <stdio.h>
#define LIMIT_POSTAL 8
#define LIMIT_REGISTER 5
#define LIMIT_ADDRESS 20
char postal_c[LIMIT_REGISTER][LIMIT_POSTAL], address[LIMIT_REGISTER][LIMIT_ADDRESS];
int line;
void reg()
{
int op;
do
{
printf("Address: ");
scanf("%s", &address[line]);
printf("Postal code: ");
scanf("%s", &postal_c[line]);
op = -1;
printf("1 - Continue\nAny number - Exit\n");
scanf("%d", &op);
line++;
} while(op == 1);
}
int main()
{
int i;
reg();
for(i = 0; i < line; i++)
{
printf("Address: %s\n", address[i]);
printf("Postal: %s\n", postal_c[i]);
}
return 0;
}
I can't see you had initialized line variable in you program and you are using it directly to pointing the index, hence you didn't assigned any value so probably it contains garbage value and pointing invalid memory address in your program.
I am assuming your rest code is correct.
try doing...
int line =0;

Why is my Struct member changing when it isn't supposed to?

I've written this code in C where I want to increment the balance of a account if it is found with a matching string ID using the increaseBalance function, and although it does increment the balance value, it also changes the value of the structs ID as well. Here is my code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_ACCOUNT_NUM 1000
#define NAME_LEN 15
#define ACCOUNT_NUM_LEN 6
#define FILE_LEN 20
struct bank_account
{
char owner_first_name[NAME_LEN], owner_last_name[NAME_LEN], account_num[ACCOUNT_NUM_LEN];
int balance;
};
typedef struct bank_account Account;
void reg_new_acc(Account account_reg[], int *nrOfAccounts);
Account create_user(char owner_first_name[], char owner_last_name[], char account_num[]);
void accountManagement(Account account_reg[],int *nrOfAccounts);
void print_account(Account account_reg[], int *pNrOfAccounts);
int checkAccountNum(Account account_reg[],char account_num[], int *nrOfAccounts);
void increaseBalance(Account account_reg[], char accountNum[], int amount, int *nrOfAccounts);
int main(void)
{
Account account_reg[MAX_ACCOUNT_NUM];
int nrOfAccounts = 0;
char accountFile[FILE_LEN];
//readFromFile(account_reg, &nrOfAccounts, accountFile);
accountManagement(account_reg, &nrOfAccounts);
return 0;
}
void accountManagement(Account account_reg[],int *nrOfAccounts)
{
int choice = 0;
do
{
printf("(1) Create New Account \n(2) Print All Accounts\n(3) Increment Account Balance\n");
printf("\n\nEnter Number: ");
scanf("%d", &choice);
switch (choice)
{
case 1:
reg_new_acc(account_reg, nrOfAccounts);
break;
case 2:
print_account(account_reg, nrOfAccounts);
break;
case 3:
printf("Please Enter the Account Number: ");
char accountNumber21[ACCOUNT_NUM_LEN];
scanf("%126s", accountNumber21);
printf("Please Enter the Amount: ");
int amount=0;
scanf("%d", &amount);
increaseBalance(account_reg, accountNumber21,amount, nrOfAccounts);
break;
}
} while ( choice != 9);
}
void reg_new_acc(Account account_reg[], int *nrOfAccounts)
{
char owner_first_name[NAME_LEN], owner_last_name[NAME_LEN], account_num[ACCOUNT_NUM_LEN];
while (*nrOfAccounts < MAX_ACCOUNT_NUM)
{
printf("\nRegistering User\n");
printf("Please enter (6-dig) ID number (q for quiting): ");
scanf("%s%*c", account_num);
if (strcmp(account_num, "q") == 0)
{
printf("Avslutar\n");
return ;
}
while(checkAccountNum(account_reg, account_num, nrOfAccounts)==0)
{
printf("This Already Exists\n");
printf("Please Enter Again: ");
scanf("%s%*c", account_num);
}
printf("Enter Name and Lastname: ");
scanf(" %s",owner_first_name);
scanf(" %s", owner_last_name);
account_reg[*nrOfAccounts] = create_user(owner_first_name, owner_last_name, account_num);
(*nrOfAccounts)++;
}
}
int checkAccountNum(Account account_reg[],char account_num[], int *nrOfAccounts)
{
if(strcmp(account_num, "q") == 0)
{
accountManagement(account_reg , nrOfAccounts);
}
for(int i = 0; i < *nrOfAccounts; i++)
{
if(strcmp(account_num,account_reg[i].account_num) == 0)
{
return 0;
}
}
return 1;
}
Account create_user(char owner_first_name[], char owner_last_name[], char account_num[])
{
Account account;
strcpy(account.account_num, account_num);
strcpy(account.owner_first_name, owner_first_name);
strcpy(account.owner_last_name, owner_last_name);
account.balance=0;
return account;
}
void print_account(Account account_reg[], int *pNrOfAccounts)
{
int i;
printf("\nPrinting All Accounts\n");
printf("ID\tFull Name\t\tBalance (kr)\n");
printf("____________________________________________\n");
for(i = 0; i < *pNrOfAccounts; i++)
{
printf("%s\t\t%s\t%s\t\t%d\n\n", account_reg[i].account_num, account_reg[i].owner_first_name, account_reg[i].owner_last_name, account_reg[i].balance);
}
}
void increaseBalance(Account account_reg[], char accountNum[], int amount, int *nrOfAccounts)
{
for(int i = 0; i < *nrOfAccounts; i++)
{
if(strcmp(accountNum,account_reg[i].account_num) == 0)
{
printf("In Increase");
account_reg[i].balance+=amount;
}
}
}
If you run this code and after adding a user, try to increment the user account balance and then print out the user details, you will see that something strange has happened to the user ID number. I don't know why this is happening. Thank you for the time.
From the code, change the value for ACCOUNT_NUM_LEN to 7 to take care of the null terminator. This should fix your problem.
Remember that c string are null terminated. The null terminator also takes up some space and should be accounted for.
"(6-dig) ID number" need 'char[7]' minimum, but ACCOUNT_NUM_LEN == 6
In function reg_new_acc(), after enter "123456" for account and "last" for owner_last_name, account variable contains "123456last".
In function create_user() strcpy(account.account_num, account_num) write "123456" to account.account_num, "last" to account.balance and '\0' cause 1-byte buffer overflow.
But operator 'account.balance=0' reset balance to 0 and account.account_num to "123456", because next byte write to '\0'.
After increaseBalance() account_reg[i].balance not 0. Therefore, the string account. account_num can get non-zero bytes after "123456" and will be printed as " 123456???".
P.S. Strictly speaking, in this program there is not a single correct operation with strings and not only with strings.
P.P.S. A good idea would be to use the latest versions of gcc or clang with stack-protector, mudflap, and _FORTIFY_SOURCE enabled, which provide some control over the use of arrays for storing strings.

(C) Print an array of structs from a function that calls other function

I cooked a code for a program that asks the user to fill in information about a person (ReadDate/ReadPerson), then it asks for the range of people the user wants to print, and the function prints these people. (PrintRange)
I don't understand why the program is not working; it's stuck on the point when it should print the person... it's means there is probably a problem in either PrintPerson or PrintDate, or in the way I am calling these functions.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
int day, month, year;
} Date;
typedef struct{
char *first_name, *last_name;
int id;
Date birthday;
} Person;
void ReadDate(Date *a)
{
printf("Enter the day: ");
scanf("%d", &a->day);
printf("Enter the month (1-12): ");
scanf("%d", &a->month);
printf("Enter the year: ");
scanf("%d", &a->year);
}
void ReadPerson(Person *b)
{
char temp_first_name[21];
char temp_last_name[21];
printf("Enter the first name: ");
gets(temp_first_name);
b->first_name = (char*)malloc(strlen(temp_first_name)+1);
strcpy(b->first_name,temp_first_name);
//need to check malloc (later)
printf("Enter the last name: ");
gets(temp_last_name);
b->last_name = (char*)malloc(strlen(temp_last_name)+1);
strcpy(b->last_name, temp_last_name);
//need to check malloc (later)
printf("Enter the id number: ");
scanf("%d",&b->id);
printf("Enter the birthday:\n");
ReadDate(&b->birthday);
}
int ReadAllDate (Person *b)
{
//Person* b;
int count=1;
char choice;
printf("Would you like to enter a person?(y,n)\n");
choice = getchar();
while(choice == 'y')
{
b = (Person*)malloc(1 * sizeof(Person));
getchar();
ReadPerson(b);
printf("Done!\n");
count++;
getchar();
printf("Would you like to add a person?(y,n)\n");
choice = getchar();
}
count--;
printf("The number of entered persons is %d\nBye\n", count);
return count;
}
void PrintPerson(Person b)
{
printf("%s %s %d\n", b.first_name, b.last_name, b.id);
}
void PrintDate(Date a)
{
printf("%d // %d // %d\n",a.day,a.month,a.year);
}
void PrintRange(Person *b,int count,int ind1,int ind2)
{
int i;
if (ind1<0 || ind1>ind2 || ind2>count)
{
printf("error! you slip out from the limits of the array.\n");
}
else
{
for (i=ind1; i<=ind2; i++)
{
PrintPerson(*(b+i));
PrintDate((b+i)->birthday);
}
}
}
int main(int argc, const char * argv[])
{
Person* b;
int count;
int ind1, ind2;
count = ReadAllDate(b);
printf("insert the first index (the smaller): ");
scanf("%d", &ind1);
printf("insert the second index (the bigger): ");
scanf("%d", &ind2);
PrintRange(b, count, ind1, ind2);
}
The problem is that nowhere you are actually creating an array of Person objects. The function ReadAllDate() never changes the value of the variable b in main(). Instead, for every person you read in, it allocates memory for it, and stores the pointer to that Person in the local variable b in ReadAllDate(). Every time it does it, it forgets the previous value of b.
In main(), the value of b is unitinialized all the time. When you are trying to print persons, it will most likely crash or print garbage.
I see other issues with your code:
Don't use gets(), always use fgets(). The former can write past the end of the buffer you are providing.
Don't do malloc(strlen(...))+strcpy(), use strdup().
Start with count = 0, that way you don't need the count-- in ReadAllDate(). As a computer programmer, it's best to count from zero instead of one.
Write b[i] instead of *(b+i), and b[i].birthday instead of (b+i)->birthday.

C Structure Declaration Issue

I am writing the following program for my Programming Fundamentals Class (C Programming). My IDE is giving me a compile error for the declaration of 'student' as referenced in the lines where user input is read. It is also giving me an error on ISO C standards for nested functions in the letter_grade function. Any help would greatly be appreciated.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX 20
char letter_grade(float a, float b, float c);
int main(void)
{
char temp_name[MAX];
int count=0, last, temp;
struct student {
char f_name[MAX];
char l_name[MAX];
float test1;
float test2;
float test3;
};
printf("Please enter the student's last name (Enter ZZZ to exit): ");
gets(temp_name);
while (strncmp(temp_name, "ZZZ\0", 4))
{
strncpy(student[count].l_name, temp_name, MAX+1);
printf("Please enter the students first name: ");
scanf("%s", &student[count].f_name);
getchar();
printf("Enter the first test score: ");
scanf("%f", &student[count].test1);
printf("Enter the second test score: ");
scanf("%f", &student[count].test2);
printf("Enter the third test score: ");
scanf("%f", &student[count].test3);
printf("\nPlease enter the student's last name (Enter ZZZ to exit): ");
gets(temp_name);
count++;
}
last = count;
temp = last + 1;
printf("\t\t\tStudent Grade Report");
for (last;last>=0;last--){
printf("%s, ", student[last].l_name);
printf("%s ", student[last].f_name);
printf("\t\t Grade: %c\n\n ", letter_grade(student[last].test1, student[last].test2, student[last].test2));
// printf("Test Grade: %c\n", letter_grade(85,88,82));
return 0;
}
char letter_grade(float *a, float *b, float *c)
{
float sum = *a+*b+*c;
if (sum >= 270.0f)
return 'A';
if (sum>= 240.0f && sum <270.0f)
return 'B';
if (sum>= 210.0f && sum <240.0f)
return 'C';
if (sum>= 180.0f && sum <210.0f)
return 'D';
if (sum < 180.0f)
return 'F';
}
You nowhere declared an array or a pointer with name student. The name was not declared. Thus the code where you are refering the name like this statement
strncpy(student[count].l_name, temp_name, MAX+1);
^^^^^^^
is invalid.
What is "student"? Where is it declared?
You only declared type struct student but it is not the same as an object with name student.
Also in this loop
for (last;last>=0;last--){
printf("%s, ", student[last].l_name);
printf("%s ", student[last].f_name);
printf("\t\t Grade: %c\n\n ", letter_grade(student[last].test1, student[last].test2, student[last].test2));
there is absent the closing brace.
Applying all the comments and correcting other problems in the posted code there were many results in:
#include <stdio.h>
#include <string.h>
#define MAX_NAME_LEN (20)
#define MAX_STUDENTS (100)
// define the student struc
struct student
{
char f_name[ MAX_NAME_LEN ];
char l_name[ MAX_NAME_LEN ];
float test1;
float test2;
float test3;
};
char letter_grade(float a, float b, float c);
int main(void)
{
// define an array of 100 instances of the student struct
struct student students[ MAX_STUDENTS ];
printf("Please enter the student's last name (Enter ZZZ to exit): ");
int count=0;
while( count < MAX_STUDENTS && scanf( " %19s", students[count].l_name) && strcmp( students[count].l_name, "ZZZ" ) )
{
printf("Please enter the students first name: ");
scanf(" %19s", students[count].f_name);
printf("Enter the first test score: ");
scanf("%f", &students[count].test1);
printf("Enter the second test score: ");
scanf("%f", &students[count].test2);
printf("Enter the third test score: ");
scanf("%f", &students[count].test3);
count++;
printf("\nPlease enter the student's last name (Enter ZZZ to exit): ");
} // end while
printf("\t\t\tStudent Grade Report");
for ( ; count>=0; count--)
{
printf("%s, ", students[count].l_name);
printf("%s ", students[count].f_name);
printf("\t\t Grade: %c\n\n ",
letter_grade( students[count].test1,
students[count].test2,
students[count].test2));
} // end for
} // end function: main
char letter_grade(float a, float b, float c)
{
float sum = a+b+c;
char grade;
if( sum >= 270.f) grade = 'A';
else if (sum>= 240.0f) grade = 'B';
else if (sum>= 210.0f) grade = 'C';
else if (sum>= 180.0f) grade = 'D';
else grade = 'F';
return grade;
} // end function: letter_grade
You can compare the posted code to the above answer to spot where there were problems in the posted code.
Do not #include header files those contents are not used.
A passed value to a function does not become a pointer in the parameter list of the called function.
In any if then else sequence, there is no need to re-test for previously eliminated values
The posted code nested one function inside another, That is not valid C code, although can be allowed with the gcc compiler extension.
There is no need for a return statement from main() if the returned value is 0.
On any non void function, ALL paths through the code must lead to a return value; statement.
The posted code failed to declare any instance of the struct student structure. And certainly did not declare an array of those struct instances, as is needed when multiple students being processed.
The posted code (and this answer) will fail if any first or last name is greater than or equal to 20 characters.
This answer does not check for failures of the call to scanf() but for reliability, such checking for each must be performed. Similar to:
if( 1 != scanf( " %19s", students[count].l_name) )
{
perror( "scanf failed" );
exit( EXIT_FAILURE ); // `exit()` and `EXIT_FAILURE` found in stdlib.h
}
// implied else, scanf successful
The while() statement in the main() function is very 'busy' for clarity, the call to strcmp() could be extracted and placed in a following statement similar to:
while(...)
{
if( !strcmp( students[count].l_name, "ZZZ" ) {
{
break;
}
...
In general, never trust the input from a user. That is why the returned value (not the parameter value) from each call to scanf() needs to be checked.
As a simplification, rather than hardcoding the MAX LENGTH modifier in the calls to scanf() with a %s format specifier, can use the following changes:
#define MAX_NAME_LEN (19)
...
struct student
{
char f_name[ MAX_NAME_LEN+1 ];
char l_name[ MAX_NAME_LEN+1 ];
float test1;
float test2;
float test3;
};
....
&& scanf(" %" MAX_NAME_LEN "s", students[count].l_name) &&
....
scanf(" %" NAX_NAME_LEN "s", students[count].f_name);

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