How to change values of a struct passed to a function - c

Hi friends I am practicing structures. I have these two functions one returns the structure and I copy that to the local struct in main. My second function changes those local struct members by entering different entities.
Now I have printed result after calling each function, to my surprise I notice that printed result after both the function are same. I am unable to understand what is happening here…can you guys please explain me…thanks!
#include <stdio.h>
#include <stdlib.h>
struct student{
char name[30];
float marks;
};
struct student read_student();
void read_student_p(struct student student3);
void print_student(struct student student2);
int main()
{
struct student student1;
student1 = read_student();
print_student(student1);
read_student_p(student1);
print_student(student1);
system("pause");
return 0;
}
//This is my first function
struct student read_student()
{
struct student student2;
printf("enter student name for first function: \n");
scanf("%s",&student2.name);
printf("enter student marks for first function:\n");
scanf("%f",&student2.marks);
return student2;
}
//function to print
void print_student(struct student my_student)
{
printf("Student name in first function is : %s\n",my_student.name);
printf("Student marks in first function are: %f\n",my_student.marks);
};
//My second function
void read_student_p(struct student student3)
{
printf("enter student name for second function: \n");
scanf("%s",&student3.name);
printf("enter student marks for second function: \n");
scanf("%f",&student3.marks);
}

Do you mean to write
void read_student_p(struct student* student3)
^
{
read_student_p(&student1);
^
You need to pass a pointer to read_student_p if you want to modify the struct that you are passing. Currently it is passed by value, and the modifications are lost.
Considering the _p suffix, I expect that this was intended..

When you do this:
read_student_p(student1);
And the method looks like this:
void read_student_p(struct student student3)
{
printf("enter student name for second function: \n");
scanf("%s",&student3.name);
printf("enter student marks for second function: \n");
scanf("%f",&student3.marks);
}
Structs in C are passed by value, not by reference.
So what read_student_p does is take a copy of the struct you pass in (student1), edit the copy, and then do nothing.
One solution would be to return the changed version of the struct. Another version would be to pass a pointer to a struct, and edit the struct via pointer (so that you're editing the same copy of the struct directly).

In the second function read_student_p you were calling by value, which is to say, you defined a new struct variable tmp in the function, and copied the value of student1 to this tmp value. All the modifications that you've done were on tmp value, which wouldn't affect student1.

Related

Can't edit integer of a struct [duplicate]

Hi friends I am practicing structures. I have these two functions one returns the structure and I copy that to the local struct in main. My second function changes those local struct members by entering different entities.
Now I have printed result after calling each function, to my surprise I notice that printed result after both the function are same. I am unable to understand what is happening here…can you guys please explain me…thanks!
#include <stdio.h>
#include <stdlib.h>
struct student{
char name[30];
float marks;
};
struct student read_student();
void read_student_p(struct student student3);
void print_student(struct student student2);
int main()
{
struct student student1;
student1 = read_student();
print_student(student1);
read_student_p(student1);
print_student(student1);
system("pause");
return 0;
}
//This is my first function
struct student read_student()
{
struct student student2;
printf("enter student name for first function: \n");
scanf("%s",&student2.name);
printf("enter student marks for first function:\n");
scanf("%f",&student2.marks);
return student2;
}
//function to print
void print_student(struct student my_student)
{
printf("Student name in first function is : %s\n",my_student.name);
printf("Student marks in first function are: %f\n",my_student.marks);
};
//My second function
void read_student_p(struct student student3)
{
printf("enter student name for second function: \n");
scanf("%s",&student3.name);
printf("enter student marks for second function: \n");
scanf("%f",&student3.marks);
}
Do you mean to write
void read_student_p(struct student* student3)
^
{
read_student_p(&student1);
^
You need to pass a pointer to read_student_p if you want to modify the struct that you are passing. Currently it is passed by value, and the modifications are lost.
Considering the _p suffix, I expect that this was intended..
When you do this:
read_student_p(student1);
And the method looks like this:
void read_student_p(struct student student3)
{
printf("enter student name for second function: \n");
scanf("%s",&student3.name);
printf("enter student marks for second function: \n");
scanf("%f",&student3.marks);
}
Structs in C are passed by value, not by reference.
So what read_student_p does is take a copy of the struct you pass in (student1), edit the copy, and then do nothing.
One solution would be to return the changed version of the struct. Another version would be to pass a pointer to a struct, and edit the struct via pointer (so that you're editing the same copy of the struct directly).
In the second function read_student_p you were calling by value, which is to say, you defined a new struct variable tmp in the function, and copied the value of student1 to this tmp value. All the modifications that you've done were on tmp value, which wouldn't affect student1.

Passing structures to functions in C programming

Declared structures:
typedef struct{
char fname[25];
char mname[3];
char lname[25];
}Name;
typedef struct{
char month[25];
int day,year;
}Date;
typedef struct{
Name gname;
char addr[50];
char cnum[11];
}Guardian;
typedef struct{
Name sname;
Date sbday;
Guardian sguard;
char gender[6];
char addr[50];
char cnum[11];
char course[10];
int year;
}Student;
Declared functions:
void input(Name name,Date date, Guardian guard, Student stud);
void display(Name name,Date date, Guardian guard, Student stud);
When input function is called, it lets me add strings being asked. Then, display function is called. It will not display the entered information.
Calling functions:
input(name, date, guard, stud);
display(name, date, guard, stud);
Display funtion:
void display(Name name, Date date, Guardian guard, Student stud)
{
printf(" -=Student Information=- \n");
printf("Name: %s %s. %s\n",stud.sname.fname,stud.sname.mname,stud.sname.lname);
printf("Birtday: %s %d, %d\n",stud.sbday.month,stud.sbday.day,stud.sbday.year);
printf("Gender: %s\n",stud.gender);
printf("Contact Number: \n%s",stud.cnum);
printf("Course & Year: %s-%d \n",stud.course,stud.year);
printf(" -=Student Guardian Information=- \n");
printf("Name: %s %s. %s\n",guard.gname.fname,guard.gname.mname,guard.gname.lname);
printf("Address: %s\n",guard.addr);
printf("Contact Number: %s\n",guard.cnum);
}
Input function:
void input(Name name,Date date, Guardian guard, Student stud)
{
printf("Student Information \n");
printf("First Name: ");
gets(stud.sname.fname);
//...
}
This will just display one set of information. It won't add new records per say. Just a simple exercise.
C is pass by value. So when you passed a variable as you have shown - a copy of it is given to the called function so that it can work with it. As a result the object from which the copy is made remains unchanged. The solution is to pass the address of the object and then dereferencing the copied pointer variable which contains the address of the object - thus changing the intended object.
So in your case,
void input(Name *name,Date *date, Guardian *guard, Student *stud){
printf("%s",name->fname); // short hand for (*name).fname
...
}
Call it like
input(&name, .. );
Even if you want only read those objects(you don't want to change anything) then also I would support this way of doing things - why burden things by copying those large structure instances? Just pass the address of them and work with it.
Also don't use deprecated gets - use fgets instead and when you use it (fgets) don't forget to check the return value.
Like how to modify the content of a variable througth a function, you need to give the address of the structure, because "deep down", a variable of type "int" and a variable of type "struct something", well, it's a variable.
And if you want to modify the value of your variable, you need to send his address (pointer).
Also, note that by passing the value of the struct, the value are copied. For small structure, it doesn't really matter, but for "larger" one, it will cost really huge on your program's speed.

C Programming: How to create a linked list using a struct within a struct

So I'm trying to create a database of students with a struct with their names as the primary and other factors such as gender, age. Also in that struct, is another struct that contains the student's class grades: How would I do that?
Your basic problem in understanding is that you have your students structure wrong and it is misguiding you. Look at this and try to understand how it works and why it is what you need and how you can use it to solve your problems:
struct student{
char name[20];
int age;
char gender[7];
struct grades gr;
struct student *nextStudent;
};
your print function, could look like this
void print (void){
for(struct student *stud = root; stud != NULL; stud = stud->nextStudent){
printf("Name: %s\n",stud->name);
printf("Grades: %s, %s, %s, %s\n", stud->gr.math, stud->gr.history, stud->gr.science, stud->gr.writing);
}
}
if the question is 'how do I access the grades struct in student struct?' The answer is like this - assuming st is a student instnace pointer
st->grades.math[0] = 'A'

nested structs - input

i need to input name to a variable (first name*) in a struct
with a malloc
i don't understand why to program is fail to run.
im inserting the name (for example David)
and its should gets the name and put it in temp array
and then to resize the pointer first_name*
and copy the string temp to first_name*
someone can help me understand why its doesn't work?
look for the function "ReadPerson".
typedef struct{
int day, month, year;
} Date;
typedef struct{
char *first_name, *last_name;
int id;
Date birthday;
} Person;
void ReadDate(Date *a)
{
printf("insert day, month, year\n");
scanf("%d%d%d", &a->day, &a->month,&a->year);
}
void ReadPerson(Person *b)
{
char temp_first_name[21];
char temp_last_name[21];
printf("insert first name:\n");
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("insert last name:\n");
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("insert id\n");
scanf("%d",&b->id);
printf("insert person's birthday:\n");
ReadDate(b);
}
Thanks.
i don't understand why to program is fail to run
Well, it's because you're trying to substitute incompatible types and decent compiler should have told you about that.
Let's look at the end of function void ReadPerson(Person *b):
{
...
ReadDate(b); // error here
}
As you can see b is of type Person * and you pass it to the function void ReadDate(Date *a) which expects a Date * type.
So it is probably a simple typo, just change to this: ReadDate(&b->birthday);.

Passing an element of an array of structs in C

I was trying to pass one of the 20 "database" structs I made
here is my prototype for the function "add"
void add(struct database test);
I want to pass my database struct and for now i'll just call it "test"
Here is my database structure
struct database
{
char ID[6];
char Duration[3];
};
main()
{
char menu;
struct database employee[20]; // I make 20 employee variables
int a = 0; /*A counter I use to edit certain structs
ie a=2 "employee[a]" = "employee[2]" */
I then call the function like this:
add(employee[a]);
a++; /*Once it exits this I want it to go to the next employee
variable so I increment the counter */
The actual function looks like this:
void add(struct database test)
{
static int a = 0;
printf("\nPlease enter a 5 digit employee number: ");
scanf("%s", test[a].ID);
a++
}
while doing this I get the error:
Error E2094 Assignment.c 64: 'operator+' not implemented in type 'database' for arguments of type 'int' in function add(database)
It says the error is at
scanf("%s", test[a].ID);
Thanks in advance for any help, and I apolgise if I have formatted this wrong, still learning for to use stack overflow, so sorry!
This is what you need to do in order to get it right:
void add(struct database* test)
{
printf("\nPlease enter a 5 digit employee number: ");
scanf("%s",test->ID);
}
int main()
{
...
int a;
struct database employee[20];
for (a=0; a<sizeof(employee)/sizeof(*employee); a++)
add(&employee[a]); // or add(employee+a);
...
}
add(struct database test) declares a struct database as parameter. This is not an array, so you cannot index it.
So
test[a]
is invalid.
Also the int a inside add() is different from the int a defined in main(). Inside add() the latter a is hidden by the former a.
Also^2 you are passing to add() a copy of the array's element declared in main(). So any modifications done to test in side add() are lost when returning from add(). They won't be visible in the array declated in main().

Resources