simple pointer to structures - c

I am trying to write simple program to collect data for certain number of students and output it in the end. After I enter data for one student, my program crashes.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
typedef struct Student Student;
struct Student{
char name[20];
char lastname[20];
int age;
};
main() {
int i;
int n;
scanf("%d",&n);
Student *pStudents = NULL;
pStudents = (Student*)malloc(n*sizeof(Student));
for(i=0;i<n;i++) {
printf("Enter the students name: \n");
scanf("%s",(pStudents+i)->name);
printf("Enter lastname: \n");
scanf("%s",(pStudents+i)->lastname);
printf("Enter age: \n");
scanf("%d",(pStudents+i)->age);
}
for(i=0;i<n;i++) {
printf("%s",(pStudents+i)->name);
printf("%s",(pStudents+i)->lastname);
printf("%d",(pStudents+i)->age);
}
}
Thanks in advance.

scanf("%d",(pStudents+i)->age);
the argument of scanf must be of a pointer type.
Change (pStudents+i)->age to &(pStudents+i)->age.

Related

The first module of my program and it's not working properly

I want to take a number input from the user. I want it to work as a user defined array of structure.
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
int main(void)
{
struct Data
{
char Name[10];
int Age;
char Gender;
};
int i, n;
struct Data D[n];
printf(" \n enter the number of user : ");
scanf("%d",&n);
printf("enter the User details :");
for(i=0;i<n;i++)
scanf("%s" "%d" "%c",D[i].Name,&D[i].Age,&D[i].Gender);
return 0;
}
Try using this instead , if you want to declare an array with unknown number of parts , you must read the n value from the user first , and then procced in your programm , quick note : " The struct declaration is an alternatif you can use but the one you used is also correct " , hope I helped you ;)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct
{
char Name[10];
int Age;
char Gender;
}Data;
int main()
{
int i, n;
printf(" \n enter the number of users : ");
scanf("%d",&n);
Data D[n];
printf("enter the users details ....\n\n");
for(i=0;i<n;i++){
printf("Enter the user number %d informations : \n",i+1);
scanf("%s %d %c",D[i].Name,&D[i].Age,&D[i].Gender);
}
return 0;
}

C program - skipping user input

I created a program that uses arrays and array pointers to store a user's animal name, category of animal, and age. But when I run it, there is a segmentation fault after I type the name age and category. I was wondering if someone could guide me in how to fix it, I am very new to C programming.
This is the task I am supposed to complete:
Write a program that defines an animal data type, with an animal name, age, and category (cat, dog, etc.), as well as an animal array type that stores an array of animal pointers.  Your program will prompt the user to enter the data for as many animals as they wish.  It will initialize a dynamically allocated animal structure for each animal, and it will store each animal in an instance of the animal array structure.  Your program will then print all the animal information to the screen.  You will upload your C program as one file.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
char *name;
char *category;
int age;
} AnimalType;
typedef struct {
AnimalType basicInfo;
AnimalType *arr[];
} AnimalArrayType;
void initAnimal(char *n, char *c, int a, AnimalArrayType *ar);
void printAnimal(const AnimalArrayType *stuPtr);
int main() {
AnimalArrayType *array;
int numAn;
char name[20];
char category[20];
int age;
printf("Please enter the number of animals you want to input: ");
scanf("%d", &numAn);
array = calloc(numAn, sizeof(AnimalArrayType));
for (int i=0; i<numAn; ++i) {
printf("Enter animal name: ");
scanf("%s", name);
printf("Enter their category: ");
scanf("%s", category);
printf("Enter age: ");
scanf("%d", &age);
initAnimal(name, category, age, array + I);
}
printf("\n LIST:\n");
for (int i=0; i<numAn; ++i) {
printAnimal(array + I);
}
return 0;
}
void initAnimal(char *n, char *c, int a, AnimalArrayType *ar)
{
strcpy(ar->basicInfo.name, n);
strcpy(ar->basicInfo.category, c);
ar->basicInfo.age = a;
}
void printAnimal(const AnimalArrayType *stuPtr)
{
printf("Animal: %s, Category: %s age %d\n",
stuPtr->basicInfo.name, stuPtr->basicInfo.category,
stuPtr->basicInfo.age);
}
The char *name and char *category fields in the AnimalType struct are being initialized to NULL (from the call to calloc()), but you don't allocate any char[] memory for them to point at afterwards, so you end up crashing in initAnimal() when it tries to copy data into those fields using strcpy().
You need to either:
change those fields into char[] arrays instead of char* pointers:
typedef struct {
char name[20];
char category[20];
int age;
} AnimalType;
allocate memory for them to point at, such as from strdup():
typedef struct {
char *name;
char *category;
int age;
} AnimalType;
...
void initAnimal(char *n, char *c, int a, AnimalArrayType *ar)
{
ar->basicInfo.name = strdup(n);
ar->basicInfo.category = strdup(c);
ar->basicInfo.age = a;
}
Don't forget to free() anything you dynamically allocate when you are done using it.

Structure function pointer parameter?

Fields of Student:​ name, lastName, studentId, mid1Grade, mid2Grade, finalGrade, average
Fields of Course:​ courseName, courseCode, myStudentArray (array of Student structures),currentStudentCount
Functions:
void createNewStudent(struct Course *myCourse);
void setGradeOfStudent(struct Course *myCourse);
void findAndDisplayAverage(struct Course *myCourse);
struct Student * findStudentByID(int id, struct Course *myCourse);
void displayAverageOfAllStudents(struct Course *myCourse);
void displayAverageOfStudentsInInterval(struct Course *myCourse
ok so I have written the first function but there is an error which I dont understand. First of all the first function and what it does:
createNewStudent:​ Prompt the user to enter name, last name and id of the new student.Values entered by the user are assigned to the fields of the student residing in themyStudentArray ​of course variable pointed by ​myCourse​. ​currentStudentCount ​will be updated so that it designates the slot allocated for the student inserted next.
and my implementation:
#include <string.h>
#include <stdio.h>
struct Student {
char name[50];
char lastname[50];
int id;
int mid1;
int mid2;
int final;
double average;
};
struct Course {
char courseName[50];
char courseCode[50];
struct Student myStudentArray[5];
int currentstudentcount;
};
void createNewStudent(struct Course * myCourse);
void setGradeOfStudent(struct Course * myCourse);
void findAndDisplayAverage(struct Course * myCourse);
struct Student * findStudentByID(int id, struct Course * myCourse);
void displayAverageOfAllStudents(struct Course * myCourse);
void displayAverageOfStudentsInInterval(struct Course * myCourse);
int main() {
struct Student * stud;
int input = 0;
scanf("%d", & input);
if (input == 1) {
createNewStudent(struct Course * myCourse);
}
}
return 0;
}
void createNewStudent(struct Course * myCourse) {
struct Student s1;
printf("Enter name: ");
scanf("%[^\n]%*c", s1.name);
printf("Enter Surname: ");
scanf("%[^\n]%*c", s1.lastname);
printf("Enter id: ");
scanf("%d", & s1.id);
}
When you call the function with the if(input == 1) it gives
error: expected expression before ‘struct’
but I dont understand this beacuse *myCourse is just a pointer to the Course struct isn't it ????
If I can understand this ı will be able to the the next functions I think
Is the function correct ?? I dont know why this doesnt work
Ok I tried to use the struct Student myStudentArray[5]; to get name, lastname,id like so (structs are the same)
void createNewStudent(struct Course *myCourse);
void setGradeOfStudent(struct Course *myCourse);
int main(){
struct Course *myCourse;
int input=0;
scanf("%d",&input);
if(input == 1){
createNewStudent(myCourse);
}
return 0;
}
void createNewStudent(struct Course *myCourse){
myCourse->currentstudentcount=0;
printf("Enter name: ");
scanf("%[^\n]%*c"
,myCourse->myStudentArray[myCourse->currentstudentcount].name);
printf("Enter Surname: ");
scanf ("%[^\n]%*c",
myCourse->myStudentArray[myCourse->currentstudentcount].name);
myCourse->currentstudentcount++;
}
I Keep getting
may be used uninitialized in this may be used uninitialized in this function [-Wmaybe-uninitialized]
and
Segmentation errors
void createNewStudent(struct Course * myCourse)
If you want to create new student, you should use the student struct as the parameter of this function instead of using struct Course.
void createNewStudent(struct Student *s1)
Then, this function becomes as:
void createNewStudent(struct Student *s1) {
printf("Enter name: ");
scanf("%49s", s1->name);
printf("Enter Surname: ");
scanf("%49s", s1->lastname);
printf("Enter id: ");
scanf("%d", & s1->id);
}
If you want to test, in main function, you can declare the value stud or the pointer to struct Student.
For example:
int main() {
struct Student stud;
int input = 0;
scanf("%d", & input);
if (input == 1) {
createNewStudent(&stud);
printf("name: %s\n Surname: %s\n id = %d\n", stud.name, stud.lastname, stud.id);
}
return 0;
}
The complete program for test:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
struct Student {
char name[50];
char lastname[50];
int id;
int mid1;
int mid2;
int final;
double average;
};
struct Course {
char courseName[50];
char courseCode[50];
struct Student myStudentArray[5];
int currentstudentcount;
};
void createNewStudent(struct Student *s1);
int main() {
struct Student stud;
int input = 0;
scanf("%d", & input);
if (input == 1) {
createNewStudent(&stud);
printf("name: %s\nSurname: %s\nid = %d\n", stud.name, stud.lastname, stud.id);
}
return 0;
}
void createNewStudent(struct Student *s1) {
printf("Enter name: ");
scanf("%49s", s1->name);
printf("Enter Surname: ");
scanf("%49s", s1->lastname);
printf("Enter id: ");
scanf("%d", & s1->id);
}
The output:
#./test
1
Enter name: abc
Enter Surname: def
Enter id: 100
name: abc
Surname: def
id = 100
Update for your question in the comment:
If you want to store student info in an array, you can change the code to:
struct Student myStudentArray[5];
int input = 0;
scanf("%d", & input);
if (input == 1) {
for (int i = 0; i < 5; i++) {
createNewStudent(&myStudentArray[i]);
}
for (int i = 0; i < 5; i++) {
printf("name: %s\nSurname: %s\nid = %d\n", myStudentArray[i].name, myStudentArray[i].lastname, myStudentArray[i].id);
}
}
For Course structure you can create one function as the function createNewStudent but for struct Course to create the new course. After creating new 5 students (for example the code above), you can copy the myStudentArray to new_course.myStudentArray. Then now you have the info of 5 students in new_course. When you copy value from an array to another, you can use memcpy or using one loop to copy each element from one array to another one. Do not use something like myStudentArray = new_course.myStudentArray for the array.
You are making a declaration as a parameter of the createNewStudent() function. In C, functions require expressions as parameters, which is why you got the error message "expected expression...".
So, just create the struct pointer before you call the function:
if (input == 1) {
struct Course *myCourse = malloc(sizeof(struct Course));
createNewStudent(myCourse);
}
Notice the use of malloc(), which returns a pointer to a place in memory of sufficient size to hold that particular Course struct. When dealing with pointers to structs, you need to allocate memory for the structs that will ultimately be pointed to, in order to avoid dereferencing unallocated regions of memory.
In your function CerateNewStudent, the proper way to address the variables into which to place the data read by scanf should be:
myCourse->myStudentArray[myCourse->currentstudentcount].name
as the variable to read name into. Use this syntax for all data items to read. After that, increment the counter:
myCourse->currentstudentcount++;
Note: what is missing in all your functions (and in the assignment?) is a way to create a course. The students created are all added to courses. First a course should be created and then students can be added to it.

Compiler giving an unexpected error for casting a pointer as a struct in calloc()

I want to create a dynamic array of pointers, each pointing to a diffrent structure, and the compiler gives me error: expected ')' before 'book'.I have tried struct * book, but it fails nevertheless. Why does it give this error and how to fix it?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
char book_name[32];
char book_genre[32];
char author[32];
int page_count;
float price;
}Sbook;
typedef struct
{
char library_name[32];
Sbook * bookp;
int books_count;
}Slib;
void addexistingBooks(Slib library, Sbook book, int i);
int main()
{
Slib library;
Sbook book;
int i=0;
printf("Enter amount of books inside the library: ");
scanf("%d", &(library.books_count));
library.bookp = (Sbook * book)calloc(library.books_count,sizeof(struct book*));
addexistingBooks(library, book, i);
free(library.bookp);
return 0;
}
void addexistingBooks(Slib library, Sbook book, int i)
{
for(i=0;i<library.books_count;i++)
{
printf("Enter the name of the book: \n");
fgets(library.bookp[i].book_name,32,stdin);
printf("Enter the genre of the book: \n");
fgets(library.bookp[i].book_genre,32,stdin);
printf("Enter the author of the book: \n");
fgets(library.bookp[i].author,32,stdin);
printf("Enter the page count of the book: \n");
scanf("%d", &(library.bookp[i].page_count));
printf("Enter the price of the book: \n");
scanf("%f", &(library.bookp[i].price));
fflush(stdin);
}
}

Using structs and arrays in c

This here is a small portion of a larger program I need to create to enter songs and their info into a database. I am new to using structs and my professor hasnt showed us yet on how to pass structs into functions and then using those inside main. I am also not supposed to use pointers yet. I get many errors when compiling and I'm not sure where to start.
#include <stdio.h>
typedef struct mp3song_struct {
char title[40];
char artist1[20];
char artist2[20];
char artist3[20];
int datemonth;
int dateday;
int dateyear;
char genre[10];
}mp3song;
void populate(mp3song totalsongs[30]);
int main() {
struct mp3song totalsongs[30];
populate(mp3song totalsongs);
}
void populate(mp3song totalsongs[30]){
int i = 0;
for(i = 0; i < 5; ++i){
printf("Enter song title: \n");
scanf("%c", &totalsongs[i].title);
printf("Enter Artists(If no more than 1 enter \"none\")");
printf("Enter artist: \n");
scanf("%c", &totalsongs[i].artist1);
printf("Enter artist: \n");
scanf("%c", &totalsongs[i].artist2);
printf("Enter artist: \n");
scanf("%c", &totalsongs[i].artist3);
printf("Ente date mm/dd/yyyy\n");
printf("Enter month: \n");
scanf("%d", &totalsongs[i].datemonth);
printf("Enter day: \n");
scanf("%d", &totalsongs[i].dateday);
printf("Enter year: \n");
scanf("%d", &totalsongs[i].dateyear);
printf("Enter genre: \n");
scanf("%c", &totalsongs[i].genre);
}
}
There are several problems in your code. You can declare int populate(struct mp3song, struct mp3song totalsongs[30]); as void populate(struct mp3song, struct mp3song totalsongs[30]); since you are not returning an integer.
mp3song is not an array so it cannot be subscripted like &mp3song[i]. In fact populate function cannot receive struct mp3song as it is a type not value. So modify populate function line int populate(struct mp3song totalsongs[30]); and then replace all occurances of &mp3song[i] with &totalsongs[i] and you will be able to take input in the array.
mp3song is a structure name not structure variable
you need to declare a variable of that structure type to pass a structure.
example:
struct definition
struct <struct_name>{
Struct elements;
}<struct variable>;
struct <struct_name> <struct_variable>;
In your case
you can pass only variable not struct_name
struct mp3song totalsongs[30];
populate(totalsongs[30]);
function definition
<return_type int or void> populate(struct mp3song totalsongs[30]);
Now you can access structure elements with variable name totalsongs inside the function.
modifed code of yours
#include <stdio.h>
typedef struct mp3song {
char title[40];
char artist1[20];
char artist2[20];
char artist3[20];
int datemonth;
int dateday;
int dateyear;
char genre[10];
};
void populate(struct mp3song totalsongs[30]);
int main() {
struct mp3song totalsongs[30];
populate(totalsongs);
}
void populate(struct mp3song totalsongs[30]){
int i = 0;
for(i = 0; i < 5; ++i){
printf("Enter song title: \n");
scanf("%s", &totalsongs[i].title);
printf("Enter Artists(If no more than 1 enter \"none\")");
printf("Enter artist: \n");
printf("TITLE: : %s \n",totalsongs[i].title);
scanf("%c", &totalsongs[i].artist1);
printf("Enter artist: \n");
scanf("%c", &totalsongs[i].artist2);
printf("Enter artist: \n");
scanf("%c", &totalsongs[i].artist3);
printf("Ente date mm/dd/yyyy\n");
printf("Enter month: \n");
scanf("%d", &totalsongs[i].datemonth);
printf("Enter day: \n");
scanf("%d", &totalsongs[i].dateday);
printf("Enter year: \n");
scanf("%d", &totalsongs[i].dateyear);
printf("Enter genre: \n");
scanf("%c", &totalsongs[i].genre);
}
}

Resources