I am learning structure and function and I'm trying to pass a pointer to structure as an argument. My code is to input student name,age and marks. This is my program
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct student {
char name[15];
int age;
double marks;
};
void display();
int main(){
struct student *s1;
s1 =(struct student *) malloc(sizeof(struct student));
for(int i=0; i<2; i++)
{
printf("\nEnter details of student %d\n\n", i+1);
printf("Enter name: ");
scanf("%s", s1->name);
printf("Enter age: ");
scanf("%d", &s1->age);
printf("Enter marks: ");
scanf("%f", &s1->marks);
}
display(&s1);
}
void display(struct student *s1){
printf("\nName\tAge\tMarks\n");
for(int i = 0; i<2;i++ )
{
printf("Name: %s",s1->name);
printf("\nAge: %d",s1->age);
printf("\nMarks: %.2lf",s1->marks);
}
}
the code runs but it gave a wrong outputs and garbage value. What did i do wrong?
There are several syntax error. I have included documentation in the code below.
Also, you are overwriting the content of s1 everytime when you are prompting user to input. Test it with two different data for example (name: "alex", age: 19, mark: 100.0 and name: "jason", age: 22, mark: 100.0) your program will output only the later.
To solve this, I would suggest you to allocate your student pointer before looping so that you have two distinct memory for each student and you wont overwrite them in this case.
Basically, each student struct is treated as an array and instead of s1->name you will dereference them as s1[i].name
display function declaration
void display(struct student *s1);
main function
int main()
{
int i;
struct student *s1;
s1 =(struct student *) malloc(sizeof(struct student) * 2); /* 2 = number of students */
for(i=0; i<2; i++)
{
printf("\nEnter details of student %d\n\n", i+1);
printf("Enter name: ");
scanf("%s", s1[i].name);
printf("Enter age: ");
scanf("%d", &s1[i].age);
printf("Enter marks: ");
scanf("%lf", &s1[i].marks); /* Instead of %f, it should be %lf */
}
display(s1); /* Instead of &, it should be s1 */
/* Free heap memory */
for(i=0; i<2; i++)
{
free(s1);
s1 = NULL;
}
return 0;
}
Display function, you need some modification in your display function as well
void display(struct student *s1)
{
int i;
printf("\nName\tAge\tMarks\n");
for(i = 0; i<2;i++ )
{
printf("%s\t",s1[i].name);
printf("%d\t",s1[i].age);
printf("%.2f\t",s1[i].marks); /* Instead of %.2lf, it should be %.2f */
printf("\n");
}
}
Struct for student
struct student
{
char name[15];
int age;
double marks;
};
Related
I found online the following program using struct and functions.
We call a function that fills the array. Inside the function there is the for-loop that inserts the elements that the user gives.
#include <stdio.h>
// student structure
struct student {
char id[15];
char firstname[64];
char lastname[64];
float points;
};
// function declaration
void getDetail(struct student *);
int main(void) {
// student structure variable
struct student std[3];
// get student detail
getDetail(std);
return 0;
}
// function definition
void getDetail(struct student *ptr) {
int i;
for (i = 0; i < 3; i++) {
printf("Enter detail of student #%d\n", (i + 1));
printf("Enter ID: ");
scanf("%s", ptr->id);
printf("Enter first name: ");
scanf("%s", ptr->firstname);
printf("Enter last name: ");
scanf("%s", ptr->lastname);
printf("Enter Points: ");
scanf("%f", &ptr->points);
// update pointer to point at next element
// of the array std
ptr++;
}
}
}
Is it possible to call the function "getDetail" repetitively in the main to fill the array instead of having the loop inside the function? I mean to have the for-loop in the main instead of inside the function?
I tried the following:
#include <stdio.h>
// student structure
struct student {
char id[15];
char firstname[64];
char lastname[64];
float points;
};
// function declaration
void getDetail(struct student *);
int main(void) {
// student structure variable
struct student std[3];
// get student detail
for (i = 0; i < 3; i++) {
printf("Enter detail of student #%d\n", (i + 1));
getDetail(std);
}
return 0;
}
// function definition
void getDetail(struct student *ptr) {
printf("Enter ID: ");
scanf("%s", ptr->id);
printf("Enter first name: ");
scanf("%s", ptr->firstname);
printf("Enter last name: ");
scanf("%s", ptr->lastname);
printf("Enter Points: ");
scanf("%f", &ptr->points);
// update pointer to point at next element
// of the array std
ptr++;
}
But it seems that this doesn't work. What do I have to change?
In the "getDetail" function why when the input is an array we do not use the symbol "&" and when the input is not array we use it?
So why we use only "&" before ptr->points?
Which is the difference?
ptr++; in the getDetail function will update the local variable ptr and it will vanish on returning from the function.
Have getDetail do only getting detail, and have main switch the element to receive the data.
#include <stdio.h>
// student structure
struct student {
char id[15];
char firstname[64];
char lastname[64];
float points;
};
// function declaration
void getDetail(struct student *);
int main(void) {
// student structure variable
struct student std[3];
struct student* ptr = std;
// get student detail
for (i = 0; i < 3; i++) {
printf("Enter detail of student #%d\n", (i + 1));
getDetail(ptr);
// update pointer to point at next element
// of the array std
ptr++;
}
return 0;
}
// function definition
void getDetail(struct student *ptr) {
printf("Enter ID: ");
scanf("%s", ptr->id);
printf("Enter first name: ");
scanf("%s", ptr->firstname);
printf("Enter last name: ");
scanf("%s", ptr->lastname);
printf("Enter Points: ");
scanf("%f", &ptr->points);
}
I have an assignment of dynamic allocation for an array of structs.
I'm having trouble to understand/explain why I need pointer to pointer and not like with regular array only pointer,
Maybe someone can explain?
The code as following
i added the whole code including main function.
struct Date {
int year;
int month;
int day;
};
struct Student {
char name[100];
float grades;
float points;
int id;
struct Date birth_date;
};
struct Student** get_student_data(int* number_of_student)
{
printf("how many students in your class? ");
scanf("%d", number_of_student);
struct Student** student_pointers_array = malloc(sizeof(struct Student*) * *number_of_student);
if (student_pointers_array == NULL)
return;
struct Student* student_array = malloc(sizeof(struct Student) * *number_of_student);
if (student_array == NULL)
return;
for (int i = 0; i < *number_of_student; i++)
{
printf("Enter Name\n");scanf(" %[^\n]s", &student_array[i].name);
printf("Enter Grades\n");scanf("%f", &student_array[i].grades);
printf("Enter Points\n");scanf("%f", &student_array[i].points);
printf("Enter ID\n");scanf("%d", &student_array[i].id);
printf("Enter year\n");scanf("%d", &student_array[i].birth_date.year);
printf("Enter month\n");scanf("%d", &student_array[i].birth_date.month);
printf("Enter day\n");scanf("%d", &student_array[i].birth_date.day);
student_pointers_array[i] = &student_array[i];
}
return student_pointers_array;
}
void print_student_data(struct Student** student_data, int number_of_student)
{
for (int i = 0; i < number_of_student; i++)
{
printf("name: %s\n", student_data[i]->name);
printf("average: %f\n", student_data[i]->grades);
printf("academic points: %f\n", student_data[i]->points);
printf("ID: %d\n", student_data[i]->id);
printf("birth year: %d\n", student_data[i]->birth_date.year);
printf("birth month: %d\n", student_data[i]->birth_date.month);
printf("birth day: %d\n", student_data[i]->birth_date.day);
}
}
void main()
{
int number_of_student = 0;
struct Student** student_data = get_student_data(&number_of_student);
if (student_data == NULL)
return;
print_student_data(student_data, number_of_student);
free(student_data);
}
You don't need to use struct Student ** — you can use a single level of pointers, like this:
#include <stdio.h>
#include <stdlib.h>
struct Date
{
int year;
int month;
int day;
};
struct Student
{
char name[100];
float grades;
float points;
int id;
struct Date birth_date;
};
static
struct Student *get_student_data(int *number_of_student)
{
printf("how many students in your class? ");
scanf("%d", number_of_student);
struct Student *student_array = malloc(sizeof(struct Student) * *number_of_student);
if (student_array == NULL)
return NULL;
for (int i = 0; i < *number_of_student; i++)
{
printf("Enter Name\n");
scanf(" %[^\n]s", student_array[i].name);
printf("Enter Grades\n");
scanf("%f", &student_array[i].grades);
printf("Enter Points\n");
scanf("%f", &student_array[i].points);
printf("Enter ID\n");
scanf("%d", &student_array[i].id);
printf("Enter year\n");
scanf("%d", &student_array[i].birth_date.year);
printf("Enter month\n");
scanf("%d", &student_array[i].birth_date.month);
printf("Enter day\n");
scanf("%d", &student_array[i].birth_date.day);
}
return student_array;
}
static
void print_student_data(struct Student* student_data, int number_of_student)
{
for (int i = 0; i < number_of_student; i++)
{
printf("name: %s\n", student_data[i].name);
printf("average: %f\n", student_data[i].grades);
printf("academic points: %f\n", student_data[i].points);
printf("ID: %d\n", student_data[i].id);
printf("birth year: %d\n", student_data[i].birth_date.year);
printf("birth month: %d\n", student_data[i].birth_date.month);
printf("birth day: %d\n", student_data[i].birth_date.day);
}
}
int main(void)
{
int number_of_student = 0;
struct Student* student_data = get_student_data(&number_of_student);
if (student_data != NULL)
{
print_student_data(student_data, number_of_student);
free(student_data);
}
return 0;
}
This simplifies the memory release, too. The code in the question leaks the array of structures (it only frees the array of pointers).
I must create a program focusing on the use of structures.
The program will ask the user to enter the number of students for whom he will later add specific information (name, surname, average grade).
For some reason, when I start the the program, I enter the number of students i want, after that I enter the info of the first student and then the program terminates.
Here's what I've tried.
#include <stdio.h>
#include <stdlib.h>
struct student
{
char *name;
char *surname;
float *average;
};
void inputs(struct student *a, int size);
int main()
{
int size;
printf("Enter the number of students: ");
scanf("%d", &size);
struct student *data;
data = (struct student *)malloc(size*sizeof(struct student));
if(data==NULL) {
printf("Cannot allocate memory. The program will now terminate.");
return -1;
}
inputs (data, size);
return 0;
}
void inputs(struct student *a, int size)
{
int j=0;
int i;
for(i=0; i<size; i++) {
printf("Enter the name of the student number %d: ", j+1);
scanf("%s", a->name);
printf("Enter the surname of the student number %d: ", j+1);
scanf("%s", a->surname);
printf("Enter the average grade of the student number %d: ", j+1);
scanf("%f", a->average);
j++;
a++;
}
}
This code works:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student
{
char name[30];
char surname[30];
float average;
};
void inputs(struct student *a, int size);
int main()
{
int size;
int i=0; // we need i
char string[100];
printf("Enter the number of students: ");
// scanf can be tricky lets use fgets
fgets( string , 99 , stdin );
size= atoi(string);
struct student **data; // array of struct
// get memory for the pointers to pointer
data=(struct student **) calloc( size , sizeof(char *));
// now each struct need space
for( i=0 ; i<size ; i++)
{
data[i] = malloc(sizeof(struct student));
if(data[i]==NULL) {
printf("Cannot allocate memory. The program will now terminate.");
return -1;
}// end if
}// end for loop
// input each student
for( i=0 ; i<size ; i++)
inputs (data[i], i );
return 0;
}
void inputs(struct student *a, int num)
{
int j=0;
char string[100];
// scanf can be tricky lets use fgets
printf("Enter the name of the student number %d: ", num+1);
fgets(a->name, 29, stdin);
printf("Enter the surname of the student number %d: ", num+1);
fgets( a->surname , 29, stdin);
printf("Enter the average grade of the student number %d: ", num+1);
fgets( string , 99, stdin);
a->average=atof(string);
}
I have been trying to allocate memory to the pointer variable but it keeps giving me errors or segmentation fault. How do i properly initialize the pointer variable to the course struct?
typedef struct {
char courseId[7];
char courseName[10];
} Course;
struct Student{
char firstName[10];
char lastName[10];
int studentId;
Course *course;
};
int main() {
int numStudents;
printf("How many students do you wish to register?: ");
scanf("%d", &numStudents);
struct Student *student[numStudents];
student[numStudents] = malloc(sizeof(*student[numStudents]));
student[numStudents]->course = malloc(sizeof*(numStudents * Course));
for (int i = 0; i < numStudents; i++) {
printf("Enter student #%d First Name: ", i+1);
scanf("%s", student[i]->firstName);
printf("Enter student Last Name: ");
scanf("%s", student[i]->lastName);
printf("Enter Student ID: ");
scanf("%d", &student[i]->studentId);
printf("Enter Course ID: ");
//student[i]->course = malloc(sizeof(*(student[i]->course)));
scanf("%s", student[i]->course->courseId);
printf("Enter Cousrse Name: ");
//student[i]->course = malloc(sizeof(*(student[i]->course)));
scanf("%s", student[i]->course->courseName);
}
for (int i = 0; i < numStudents; i++) {
printf("Student Name: %s %s\n", student[i]->firstName, student[i]->lastName);
printf("Student ID: %d\n", student[i]->studentId);
printf("Course Code: %s\n", student[i]->course->courseId );
printf("Course name: %s\n", student[i]->course->courseName);
free(student[i]->course);
}
You almost had it, there was a few corrections that needed to be made.
Course object in Student doesn't need to be a pointer. The array of Student structures need to be dynamically allocated then free'd later on. -> is used as a dereference operator but in your case [] is already dereferencing so you would use . instead of -> and when you allocate memory for the array of structures it needs to be the size of the structure multiplied by the number of structures. malloc(sizeof(struct Student)*numStudents);
typedef struct {
char courseId[7];
char courseName[10];
} Course;
struct Student{
char firstName[10];
char lastName[10];
int studentId;
Course course;
};
int main() {
int numStudents;
printf("How many students do you wish to register?: ");
scanf("%d", &numStudents);
struct Student* students = malloc(sizeof(struct Student)*numStudents);
for (int i = 0; i < numStudents; i++) {
printf("Enter student #%d First Name: ", i+1);
scanf("%s", students[i].firstName);
printf("Enter student Last Name: ");
scanf("%s", students[i].lastName);
printf("Enter Student ID: ");
scanf("%d", &students[i].studentId);
printf("Enter Course ID: ");
scanf("%s", students[i].course.courseId);
printf("Enter Cousrse Name: ");
scanf("%s", students[i].course.courseName);
}
for (int i = 0; i < numStudents; i++) {
printf("Student Name: %s %s\n", students[i].firstName, students[i].lastName);
printf("Student ID: %d\n", students[i].studentId);
printf("Course Code: %s\n", students[i].course.courseId );
printf("Course name: %s\n", students[i].course.courseName);
}
free(students);
return 0;
}
I tried to make minimal changes to your code.
I have a code like this for a student management system. The input function works fine but I haven't figured out why my output function stop immediately when i call it.( I know that i can not return a local array from a function in C, but i assign the array to a pointer and return that pointer, is it ok?)
Here is my code:
struct Student
{
char name[50];
char birth[25];
char gender[10];
float math, physics;
};
struct Student* input(int n, struct Student *p)
{
int i, id = 1;
struct Student s[n];
getchar();
for(i = 0; i < n; i++)
{
printf("Name: ");
fgets(s[i].name, 50, stdin);
s[i].name[strlen(s[i].name)-1] = '\0';
printf("Date of birth: ");
fgets(s[i].birth,25,stdin);
s[i].birth[strlen(s[i].birth)-1] = '\0';
printf("Gender: ");
fgets(s[i].gender,10,stdin);
s[i].gender[strlen(s[i].gender)-1] = '\0';
printf("Math = ");
scanf("%f", &s[i].math);
printf("Physics = ");
scanf("%f", &s[i].physics);
getchar();
}
p = s;
return p;
}
void outPut(int n, struct Student *p)
{
int i;
for(i = 0; i < n; i++)
{
printf("%s %s %s %f %f\n", p[i].name, p[i].birth, p[i].gender, p[i].math, p[i].physics);
}
}
int main()
{
int n;
struct Student *p, *p1;
int choice;
printf("-----------Student Management-----------");
printf("\n1. Add new students.\n2. Print student list.\n");
do
{
printf("Your choice = ");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("Number of students = ");
scanf("%d", &n);
input(n,p);
break;
case 2:
outPut(n,p);
break;
}
}
while(choice!=0);
return 0;
}
You are defining your array as a local variable. It means that it will no longer exist after the function ends. To avoid this, declare your array as a pointer and use malloc to initialize it:
struct Student *s = malloc(sizeof(Student) * n);
It will behave as a regular array and you will be able to use itself as the function return.