How to use Structures to print this output in C program? - c

Output Should be:
Please enter employee's id: 1
Please enter your full name: Jane Doe
Please enter employee's salary: 98500.9718
Employee 1 is set successfully
Please enter employee's id: 2
Please enter your full name: John Doe
Please enter employee's salary: 96500.8723
Employee 2 is set successfully
Employee 1
Name - Jane Doe
Salary - 98500.97
Employee 2
Name - John Doe
Salary - 96500.87`
My Code:
#include <stdio.h>
#include <string.h>
#define SIZE 2
struct Employee
{
int id;
char fullName[32];
double salary;
};
void setEmployee(struct Employee *);
void getFullName(char *);
void getId(int *);
void setSalary(double *);
void printEmployee(const struct Employee *);
void flushKeyboard()
{
while (getchar() != '\n');
}
int main(void)
{
struct Employee Employees[SIZE];
int i = 0;
for (i = 0;i < SIZE;i++)
{
setEmployee(Employees);
}
for (i = 0;i < SIZE;i++) {
printEmployee(Employees);
}
return 0;
}
void setEmployee(struct Employee *employee1)
{
getId(&employee1->id);
getFullName(&employee1->fullName);
setSalary(&employee1->salary);
printf("Employee %d is set successfully\n\n", (employee1->id));
}
void getFullName(char *name1)
{
printf("Please enter your full name: ");
scanf(" %31[^\n]", name1);
flushKeyboard();
}
void getId(int *identity)
{
printf("Please enter employee's id: ");
scanf("%d", &identity);
}
void setSalary(double *salary)
{
printf("Please enter employee's salary: ");
scanf("%lf", salary);
}
void printEmployee(const struct Employee *final)
{
printf("Employee: %d\n", final->id);
printf("Name: %s\n", final->fullName);
printf("Salary: %.2lf\n\n", final->salary);
}
After running this whole code, my output only shows the values that the user enters for the second for loop.
So the values will be the same. The employee number, Name and salary will be same instead of giving me 2 seperate values that user enters.
My question is why does it keep giving me same value?
I would use a for loop but i am not allowed to use a for loop for some reason.

for (i = 0;i < SIZE;i++) { printEmployee(Employees); }
Here you have forgotten to use your counting variable->
for (i = 0;i < SIZE;i++) { printEmployee(&Employees[i]); }
What happens when you pass the whole array like that is, that the array decayes to a pointer to the first element in the array which is fine for the function because it expects a pointer to an Employee struct. But then it only prints the first enployee in the array.

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

How do I stop my for loop after it iterates through an array and finds the matching element?

I have a for loop that iterates through an array of type struct but when I pass the user input to the function that retrieves the value, it prints out 10 times. I need my main() to ask the user which # of the address book to print so then it is passed to the function that prints it out but the function checks if there is a such number in the array and if there is then it prints out the values of that inputted #.
Here is the code that keeps printing the printAddress() ten times:
STRUCTURE FOR
struct addressBook
{
int entryNum;
char name[100];
char address[100];
};
void printAddress(struct addressBook addresses, int num)
{
int n = 0;
for(n=0; n < 10; n++)
{
if (addresses.checkNum == num)
{
printf("\nBELOW IS ADDRESS # %i DETAILS: \n", num);
printf("Address Book Number: %i \n", addresses.entryNum);
printf("Name: %s", addresses.name);
printf("Address: %s \n", addresses.address);
}
}
}
my main function:
int main()
{
// create a addressBook array of at least 10
struct addressBook addresses[10];
//if statements where user can select to
//add a name to address book, display a single name or quit the program
//this is if they choose to display a single name using a number
else if (choice == 2)
{
int num;
int i = 0;
printf("Enter book number: ");
scanf("%i", &num);
printAddress(addresses[i], num);
}
return 0
}
Here's an adaptation of your code that seems to work as I'd expect it to:
#include <stdio.h>
struct addressBook
{
int entryNum;
char name[100];
char address[100];
};
static
void printAddress(int n_addr, struct addressBook addresses[n_addr], int num)
{
for (int n = 0; n < n_addr; n++)
{
if (addresses[n].entryNum == num)
{
printf("\nBELOW IS ADDRESS # %i DETAILS:\n", num);
printf("Address Book Number: %i\n", addresses[n].entryNum);
printf("Name: %s\n", addresses[n].name);
printf("Address: %s\n", addresses[n].address);
}
}
}
int main(void)
{
struct addressBook addresses[10] =
{
{ 1, "John Doe", "1234 Any St, Some Town, CA 94301" },
{ 2, "Mary Fog", "1270 Some St, Any Town, CA 94303" },
{ 3, "Anne Pit", "1240 Any Rd, Some City, CA 94301" },
{ 4, "Bill Zoo", "1252 Some St, Any Town, CA 94303" },
{ 5, "Phil Tin", "1258 Any Rd, Some City, CA 94301" },
};
int num;
printf("Entry number? ");
scanf("%i", &num);
printAddress(5, addresses, num);
return 0;
}
You could add a return; or break; after the printing in the body of the if in the function. If you add return;, you can add a 'printf("Entry %d not found\n", num);` after the loop and before the function returns.
Note that you don't normally want blanks before newlines; trailing blanks are sloppy. Also, there's a newline after the name now; it looks ugly if you run the name into the tag Address:.
Given the program addr83 compiled from addr83.c, an example run is:
$ addr83
Entry number? 4
BELOW IS ADDRESS # 4 DETAILS:
Address Book Number: 4
Name: Bill Zoo
Address: 1252 Some St, Any Town, CA 94303
$

Searching for a match in a structure array

I've been at this mess for a while and I still haven't figured out where I'm going wrong with it, totally knifing myself if it's something ridiculous like a pointer.
Task shown: Trying to fill a structure array with student ID, name, last name, date of birth, and grades.. Then search by a matching ID that's given to the user.
I'd highly appreciate any help related to this subject, I've been seriously stuck at it for a while. Also I apologize in advance for the french parts
// Part 1
struct Date{
int day;
int month;
int year;
};
// Part 2
struct Student{
int ID;
char name[20];
char lastname[20];
struct Date DOB;
int notes[J];
};
// Part 3
void FillStudentList(struct Student E){
int i;
printf("\nInsert ID: ");
scanf("%d", &E.ID);
printf("Insert name: ");
scanf("%s", &E.name);
printf("Insert last name: ");
scanf("%s", &E.lastname);
printf("Insert date of birth: ");
scanf("%d %d %d", &E.DOB.day, &E.DOB.month, &E.DOB.year);
printf("Insert notes: ");
for(i=0; i<J; i++)
scanf("%d", &E.Notes[i]);
}
// Part 4
void ShowByNb(int Nb, struct Student E[], int NbStudents){
int j, i;
for(i=0; i<NbStudents; i++){
if (E[i].ID== Nb){
printf("\nID: %d", E[i].ID);
printf("\nName: %s", E[i].name);
printf("\nLast Name: %s", E[i].lastname);
printf("\nDate Of Birth: %s-%s-%s", E[i].DOB.day, E[i].DOB.month, E[i].DOB.year);
printf("\nNotes: ");
for(j=0; j<J; j++){
printf("%d", E[i].Notes[j]);
}
}
else
printf("\nInvalid Student!\n");
}
}
// Part 5
void main(){
int i, x;
struct Student E[N];
for(i=0; i<N; i++){
printf("\n\nStudent #%d", i+1);
FillStudentList(E[i]);
}
printf("\n\nSearch student by NB: ");
scanf("%d", &x);
ShowByNb(x, E, N);
}
The edited code below, I believe, achieves your goal. The main problem (other than reading/printing 'int's with '%s' was how you pass your structure to your functions. It is necessary to pass the structure by reference so that its values can be seen outside of the FillStudentList function; see this link.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define N 2
#define J 2
// Part 1
struct Dat{
int jour;
int mois;
int annee;
};
// Part 2
struct Etudiant{
int numero;
char nom[20];
char prenom[20];
struct Dat DDN;
int Notes[J];
};
// Part 3
/* Modified this so that a pointer to the struct is passed instead of a copy of the struct */
void FillStudentList(struct Etudiant *E){
int i;
printf("\nInsert ID: ");
scanf("%d", &E->numero);
printf("Insert name: ");
scanf("%s", E->nom);
printf("Insert last name: ");
scanf("%s", E->prenom);
printf("Insert date of birth: ");
/* These are integers. Do not read with %s */
scanf("%d %d %d", &E->DDN.jour, &E->DDN.mois, &E->DDN.annee);
printf("Insert notes: ");
for(i=0; i<J; i++)
scanf("%d", &E->Notes[i]);
}
// Part 4
void ShowByNb(int Nb, struct Etudiant E[]){
/* Don't redefine N == NbEtudiants making it seem that N is variable */
int j, i;
for(i=0; i<N; i++){
if (E[i].numero == Nb){
printf("\nID: %d", E[i].numero);
printf("\nName: %s", E[i].nom);
printf("\nLast Name: %s", E[i].prenom);
/* Again, can't print integers with %s */
printf("\nDate Of Birth: %d-%d-%d", E[i].DDN.jour, E[i].DDN.mois, E[i].DDN.annee);
printf("\nLes notes: ");
for(j=0; j<J; j++){
printf("%d ", E[i].Notes[j]);
}
return;
}
/* Your previous else would print invalid student every time you ran through the loop even
* if the student number was valid for a later student.
*/
}
/* Only print this if student was not found in any of the N Student structures */
printf("\nInvalid Student!\n");
}
// Part 5
void main(){
setbuf(stdout, NULL);
int i, x;
struct Etudiant E[N];
for(i=0; i<N; i++){
printf("\n\nStudent #%d", i+1);
FillStudentList(&E[i]);
}
printf("\n\nSearch student by NB: ");
scanf("%d", &x);
ShowByNb(x, E);
}
Input
1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2
Output
Student #1
Insert ID: 1
Insert name: 1
Insert last name: 1
Insert date of birth: 1
1
1
Insert notes: 1
1
Student #2
Insert ID: 2
Insert name: 2
Insert last name: 2
Insert date of birth: 2
2
2
Insert notes: 2
2
Search student by NB: 2
ID: 2
Name: 2
Last Name: 2
Date Of Birth: 2-2-2
Les notes: 2 2
classic mistake: passing parameter by value instead of by reference:
void FillStudentList(struct Student E){
.....
}
What happens here is that a local copy of your structure is created on the stack, populated with whatever the input is and destroyed when the function exits.
Generally in C, even if you don't want to modify the structure, you pass struct parameters by pointer; if you pass them by value each member of the structure is copied on to the stack...which is a waste of time an memory.
So changing the function prototype (and the code to work with the new signature) should fix the issue:
void FillStudentList(struct Student *E){
....
}

Data Structures/Records

My current program looks like this. This program should ask 5 records of a person and display them.
#include<stdio.h>
struct rec {
char name[100],address[100];
double age,mobileno;
}x;
main()
{
int i;
clrscr();
for(i=1;i<=5;i++)
{
printf("Enter Your Name: ");
scanf("%s",&x.name);
printf("Enter Your Age: ");
scanf("%lf",&x.age);
printf("Enter Your Address: ");
scanf("%s",&x.address);
printf("Enter Your Mobile No.: ");
scanf("%lf",&x.mobileno);
}
printf("\n\nThe Information has been added");
printf("\n\nNAME AGE ADDRESS MOBILE NUMBER");
for(i=1;i<=5;i++)
{
printf("\n%s %.0lf %s %.0lf",x.name,x.age,x.address,x.mobileno);
}
getch();
}
I have a problem in displaying the 5 different record. How do I display the five records in one printf?
You simply need a collection of structures to save the data into, currently you're just overwriting the data each time. There are a lot of ways to do this, but you could do something like use a static array, for example:
struct rec {
char name[100],address[100];
double age,mobileno;
};
int main() {
struct rec records[5];
for(i=0;i<5;i++) // <-- note this is 0 to 4, not 1 to 5
{
printf("Enter Your Name: ");
scanf("%s",records[i].name); // <-- don't add the & for the string input
Same for the printf() further down:
for(i=0; i<5; i++)
{
printf("Name is: %s\n", records[i].name);

how to sort specific in structs and search by last name

I want to know how I could sort elements in structs by score and search by last name.
The program also has a problem; when I enter 1 to print the records it asks me for a new entry and when I press 2 it prints the records and ask me for the entry.
So same thing for both cases — I don't know why?
#include <stdio.h>
#include <stdlib.h>
struct the_struct
{
char FirstName[20];
char LastName[32];
int Score[20];
};
int main ()
{
int i,n,z;
struct the_struct *ptr[100];
printf("how many students?\n");
scanf("%d",&n);
for (i = 0; i < n; ++i)
{
ptr[i] = malloc(sizeof(struct the_struct));
printf("Enter First Name \n");
scanf("%s",ptr[i]->FirstName);
printf("Enter Last Name \n");
scanf("%s",ptr[i]->LastName);
printf("Enter Score? \n");
scanf("%s",ptr[i]->Score);
printf("%s %s %s\n",ptr[i]->FirstName,ptr[i]->LastName,ptr[i]->Score);
}
printf("Enter the command you want to proceed to.\nprint record (press 1)\nadd new records (press 2)\ndelete record (press 3)\nSearch by last name (press 4)\nSort by score(press 5)\nSort by last name( press 6)\nFind Median score(press 7)\nExit program (press 0)\n");
scanf("%d",&z);
if (z==1);
{
for (i = 0; i<n;++i)
{
printf("%s %s %s\n",ptr[i]->FirstName,ptr[i]->LastName,ptr[i]->Score);
}
}
if (z==2);
{
ptr[i] = malloc(sizeof(struct the_struct));
printf("Enter First Name \n");
scanf("%s",ptr[i]->FirstName);
printf("Enter Last Name \n");
scanf("%s",ptr[i]->LastName);
printf("Enter Score? \n");
scanf("%s",ptr[i]->Score);
}
}
So I tried to write the sort function but it doesn't work when I print it.
if (z==5)
{
if(strcmp(The_final[i].Score,The_final[i+1].Score)>0)
{
temp = The_final[i];
The_final[i] = The_final[i+1];
The_final[i+1] = temp;
}
printf("%s %s %s\n",ptr[i]->FirstName,ptr[i]->LastName,ptr[i]->Score);
}

Resources