Issues with nested structures and dynamic memory allocation [closed] - arrays

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I'm using nested structures and dynamic memory allocation and I'm having problems.
I'm using the following input:
Member ID: 1
Member Name: A
Policy Number: 1
Policy ID: P1
Policy Type: 1
Policy Premium: 100
However, I'm not able to enter anything else after I enter P1. The program terminates.
The other issue I'm having, is that when I select option 2, which is supposed to print all members, it doesn't display correctly.
Even before entering any member details, if I choose option 2, it displays the following:
Member ID: 0
Member Name:
I'm wondering if when creating the dynamic array, I've made a mistake, and it's actually printing member[0].
After adding members to the array, then choosing option 2, it prints:
Member ID: 1
Member Name: A
Policy ID: (null)
Policy Type: Premium: $100
It prints the member details, but when it comes to accessing the policy for that member, those details don't print, and it completely skips over the
policy type.
Full code below:
#include <malloc.h>
#include <stdio.h>
enum enumtype { Car, Health, Travel, Pet };
typedef struct policy {
char id[4];
enum enumtype type;
int premium;
}pol;
typedef struct member {
int id;
char name[30];
int polnum;
pol *policy;
}mem;
mem getmember() {
mem member;
int i, j;
printf("\n\nEnter member's details");
printf("\nMember ID: ");
scanf("%d", &member.id);
printf("Member Name: ");
scanf(" %s", member.name);
printf("Requested number of policies: ");
scanf("%d", &member.polnum);
if (member.polnum > 0) {
printf("\nEnter policy details for %s", member.name);
for (i = 0; i < member.polnum; i++) {
printf("\nEnter details for policy %d", i + 1);
printf("\nEnter Policy ID: ");
scanf(" %s", member.policy->id);
printf("\nEnter Policy Type:");
printf("\n1 - Car");
printf("\n2 - Health");
printf("\n3 - Travel");
printf("\n4 - Pet");
printf("\n\nEnter an option: ");
scanf("%d", &member.policy[i].type);
while (member.policy[i].type < 1 || member.policy[i].type > 4) {
printf("\nInvalid policy type");
printf("\nPlease enter a number from 1 - 4: ");
scanf("%d", &member.policy[i].type);
}
printf("\nEnter Premium: $");
scanf("%d", &member.policy[i].premium);
while (member.policy[i].premium < 0) {
printf("Invalid premium");
printf("\nPremium must be a positive value");
printf("\nEnter Premium: $");
scanf("%d", &member.policy[i].premium);
}
}
}
else
member.policy = NULL;
return member;
}
void printmember(mem* member, int memNum) {
int i, j;
for (i = 1; i = memNum+1; i++) { // This still doesn't print properly but I don't know why
//printf("\nDetails for Member %d", i + 1);
printf("\n\nMember ID: %d", member[i].id);
printf("\nMember Name: %s", member[i].name);
for (j = 0; j < member[i].polnum; j++) {
printf("\nPolicy ID: %s", member[i].policy[j].id);
printf("\nPolicy Type: ", member[i].policy[j].type);
switch (member[i].policy[j].type) {
case 1:
printf("Car");
break;
case 2:
printf("Health");
break;
case 3:
printf("Travel");
break;
case 4:
printf("Pet");
break;
}
printf("Premium: $%d", member[i].policy[j].premium);
}
}
}
int main()
{
int choice = 0;
int memNum = 0;
char name[30];
mem* member = NULL;
member = (mem*)realloc(member, (memNum++) * sizeof(member));
while (choice != 3) {
choice = 0;
printf("\n\t Menu");
printf("\n-----------------------------");
printf("\n1 - Add new member");
printf("\n2 - Display all members");
printf("\n3 - Exit");
printf("\n\nEnter an option: ");
scanf("%d", &choice);
switch (choice) {
case 1:
member = (mem*)realloc(member, (memNum + 1) * sizeof(member));
member[memNum++] = getmember();
break;
case 2:
printf("\n\nDisplaying all members");
printmember(member, memNum);
break;
case 3:
return 0;
}
}
}

typedef struct member {
int id;
char name[30];
int polnum;
struct policy {
char id[4];
enum enumtype type;
int premium;
}pol;
}mem;
You can have n members and each member can have polnum policies, but that's not what this struct says. This struct says each member has one policy that is represented by a nested structure. Your outer realloc keeping members in an array constrains the solution space. We can't actually do that and use a stretchy structure at the same time, so I don't have to get into how. We just do this the way you already know how.
typedef struct struct policy {
char id[4];
enum enumtype type;
int premium;
} pol;
typedef struct member {
int id;
char name[30];
int polnum;
pol *policies;
}mem;
Adding policies is like so:
if (member.polnum > 0) {
member.pol = malloc(member.polnum * sizeof(pol));
printf("\nEnter policy details for %s", member.name);
for (i = 0; i < member.polnum; i++) {
//...
scanf("%d", &member.pol[i].type);
//...
}
} else {
member.pol = NULL; // When you go to write the free memory code you will thank me
}
In print member, we have a very similar construct:
for (j = 0; j < member[i].polnum; j++) {
printf("\nPolicy ID: %s", member[i].pol[j].type);
Administrative note: code was removed from question after answer posted.

Related

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

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().

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.

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(...)

how to print all id names in one loop?

This code is about 'struct' in C..
I created a struct with the properties name,roll etc.. By using the for-loop I let the user to create the struct objects. they are named as student,employee, faculty
the problem is the objects are created. But I can use them only inside the for-loop. If I want to get the value of all names in main function, it doesn't work. How can I solve it?How do i print all names in the code in only one loop
what will be the logic
#include<stdio.h>
#include<conio.h>
struct student
{
int std;
char fee[90]; //Collect Data of students
int rollno;
char name[15];
char sub[100];
};
main()
{
int x;
printf("******Enter the total number of Student from HOD*******:\n");
scanf("%d",&x);
struct student a[x];
for(int i=0;i<x;i++)
{
printf("\nEnter Rollno:\t");
scanf("%d",&a[x].rollno);
printf("\nEnter name:\t");
scanf("%s",&a[x].name);
printf("\nIs Fee Submitted:\t");
scanf("%s",&a[x].fee);
printf("\nEnter Subject name:\t");
scanf("%s",a[x].sub);
}
printf("\n****Display All Student names****");
for(int i=0;i<x;i++)
{
printf("\n%s",a[x].name);
}
//Faculty
struct faculty
{
char Fname[100];
char Sname[100];
};
int y;
printf("\n\n********Please HOD enter the total faculty members********\n");
scanf("%d",&y);
struct faculty b[y];
for(int j=0;j<y;j++)
{
printf("\nEnter Faculty Member Name:\t");
scanf("%s",&b[y].Fname);
printf("\nEnter their Subjects:\t");
scanf("%s",&b[y].Sname);
}
printf("\n****Display all Faculty Member Name****");
for(int j=0;j<y;j++)
{
printf("\n%s",b[y].Fname);
}
// Employes
struct employes
{
char ename[100];
char rank[100];
};
int z;
printf("\n\n********please HOD enter the total no of Employes*******:\n");
scanf("%s",&z);
struct employes c[z];
for(int j=0;j<y;j++)
{
printf("\nEnter the Employe name:\t");
scanf("%s",&c[y].ename);
printf("\n and enter their ranks:\t");
scanf("%s",&c[y].rank);
}
printf("\n****Display all Employe names****");
for(int j=0;j<y;j++)
{
printf("%s\n",c[y].ename);
}
}
#include<stdio.h>
#include<conio.h>
struct student
{
int std;
char fee[90];
int rollno;
char name[15];
char sub[100];
};
main()
{
int x;
printf("******Enter the total number of Student from HOD*******:\n");
scanf("%d",&x);
struct student a[x];
for(int i=0;i<x;i++)
{
printf("\nEnter Rollno:\t");
scanf("%d",&a[x].rollno);
printf("\nEnter name:\t");
scanf("%s",&a[x].name);
printf("\nIs Fee Submitted:\t");
scanf("%s",&a[x].fee);
printf("\nEnter Subject name:\t");
scanf("%s",a[x].sub);
}
printf("\n****Display All Student names****");
for(int i=0;i<x;i++)
{
printf("\n%s",a[x].name);
}
struct faculty
{
char Fname[100];
char Sname[100];
};
int y;
printf("\n\n********Please HOD enter the total faculty members********:\n");
scanf("%d",&y);
struct faculty b[y];
for(int j=0;j<y;j++)
{
printf("\nEnter Faculty Member Name:\t");
scanf("%s",&b[y].Fname);
printf("\nEnter their Subjects:\t");
scanf("%s",&b[y].Sname);
}
printf("\n****Display all Faculty Member Name****");
for(int j=0;j<y;j++)
{
printf("\n%s",b[y].Fname);
}
struct employes
{
char ename[100];
char rank[100];
};
int z;
printf("\n\n********Please HOD enter the total no of Employes*******:\n");
scanf("%d",&z); //You used %s instead of %d
struct employes c[z];
for(int j=0;j<z;j++) //You used wrong variable 'y' here
{
printf("\nEnter the Employe name:\t");
scanf("%s",&c[z].ename); //You used wrong variable 'y' here
printf("\nEnter their ranks:\t");
scanf("%s",&c[z].rank); //You used wrong variable 'y' here
}
printf("\n****Display all Employe names****");
for(int j=0;j<z;j++) //You used wrong variable 'y' here
{
printf("\n%s",c[z].ename); //You used wrong variable 'y' here
}
}
Errors:
Wrong format specifier used in taking integer input in number of Employees.
Wrong loop variable used in all loops of Employee.
Now this code is working. I've pointed out the errors in the comments also.
The loop increases i from 0 to some other value x.
(lets say x is 5 for this example)
So i has values 0, 1, 2, 3....
But regardless, you only put data into one element of the array: 5
And you keep overwriting that same element over and over again.
And 5 isn't even a valid index!! The valid indicies are 0, 1, 2, 3, 4.
5 is one-past the end of the array!

Printf displays numbers/characters incorrectly in C [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I am creating a program that simply allows users to do multiple things in one executable program. So for right now I input information into my struct variables and when the user enters "P" into the window, they're suppose to get the information back. The problem is that when it displays the results, instead of displaying '1 or 2' it displays "-0.23455558" and other silly symbols for characters. Here is my code.
C code
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<ctype.h>
typedef struct {
char fname[40];
char lname[40];
int age;
int id;
double gpa;
double price;
}student;
void Addsix(student list[]);
char Getinput();
void PrintToScreen(student list[], int count);
int main() {
student list[100];
int count = 0;
char choice;
Addsix(list);
count = 6;
choice = Getinput();
while (choice != 'Q') {
if (choice == 'P') {
PrintToScreen(list, count);
}
choice = Getinput();
}
return 0;
}
void PrintToScreen(student list[], int count) {
student temp;
int i;
for (i = 0; i < count; i++) {
printf("First Name: %c\n", temp.fname[i]);
printf("Last Name: %c\n", temp.lname[i]);
printf("Age: %d\n", temp.age);
printf("Id: %d\n", temp.id);
printf("Gpa: %.2f", temp.gpa);
printf("Price: %.2f", temp.price);
}
}
char Getinput() {
char pick;
printf("\n***************************************\n");
printf("Please select from the options below:\n");
printf("P....Print the inventory list onto the screen\n");
printf("A....Add a new entry\n");
printf("C....Clear all records\n");
printf("S....Create a current report(save it to a file)\n");
printf("D....Delete an item from the list(inventory)\n");
printf("U....Update ONE OF THE FIELDS (not THE id)\n");
printf("Q - QUIT\n");
printf("What would you like to do: ");
scanf(" %c", &pick);
pick = toupper(pick);
return pick;
}
void Addsix(student list[]) {
strcpy(list[0].fname, "Jon");
strcpy(list[0].lname, "pep");
list[0].age = 19;
list[0].id = 2713;
list[0].gpa = 4.0;
list[0].price = 2.79;
strcpy(list[1].fname, "Amanda");
strcpy(list[1].lname, "Stri");
list[1].age = 25;
list[1].id = 9654;
list[1].gpa = 3.5;
list[1].price = 2.84;
strcpy(list[2].fname, "Patrick");
strcpy(list[2].lname, "Collie");
list[2].age = 42;
list[2].id = 7748;
list[2].gpa = 2.4;
list[2].price = 74.5;
strcpy(list[3].fname, "Kim");
strcpy(list[3].lname, "Campbell");
list[3].age = 21;
list[3].id = 4508;
list[3].gpa = 3.27;
list[3].price = 2.25;
strcpy(list[4].fname, "Micky");
strcpy(list[4].lname, "Peoples");
list[4].age = 37;
list[4].id = 1478;
list[4].gpa = 4.0;
list[4].price = 10.0;
strcpy(list[5].fname, "ako");
strcpy(list[5].lname, "Imo");
list[5].age = 15;
list[5].id = 8520;
list[5].gpa = 2.90;
list[5].price = 96.5;
strcpy(list[6].fname, "Rick");
strcpy(list[6].lname, "Rolle");
list[6].age = 28;
list[6].id = 1379;
list[6].gpa = 3.8;
list[6].price = 55.2;
}
void PrintToScreen(student list[], int count) {
student temp;
int i;
for (i = 0; i < count; i++) {
printf("First Name: %c\n", temp.fname[i]);
printf("Last Name: %c\n", temp.lname[i]);
printf("Age: %d\n", temp.age);
printf("Id: %d\n", temp.id);
printf("Gpa: %.2f", temp.gpa);
printf("Price: %.2f", temp.price);
}
}
Your problem lies here. At no point do you actually access anything in the array created in the main function (and passed in as a parameter to this function). Instead, you access a variable temp created in this function, which will have arbitrary values in the members.
On top of that, since your first two members of the structure are C strings, you probably want to treat them as such rather than trying to output individual characters: i is the index within the structure array, not the character array forming the strings.
You would be better off with something like (cut down for illustration only):
void PrintToScreen(student list[], int count) {
int i;
for (i = 0; i < count; i++) {
printf("First Name: %s\n", list[i].fname);
printf("Age: %d\n", list[i].age);
}
}

Resources