goal: ask user for the number of agencies, create said agencies, and for each agency ask for the number of employees, and create those employees.
part of this will require, I think, nested structure, something like
typedef struct agence agence;
struct agence
{
char nom[20];
int nmbrEmp;
struct employe
{
char mat[20];
int nmbrEnf;
int ANC;
double SB;
double RCNSS;
}
};
is this n the right path, and how do you proceed to create the number of agencies/employees once the users gives you the number required of each.
C unlike C++ cannot have nested types, you will have to declare them separately.
struct employe
{
char mat[20];
int nmbrEnf;
int ANC;
double SB;
double RCNSS;
};
struct agence
{
char nom[20];
int nmbrEmp;
struct employe * employees; // pointer to an array of employees
};
Then use dynamic memory and populate them:
struct agence * agencies;
size_t num_agencies = 100;
agencies = calloc(sizeof(*agencies), num_agencies);
for (/* read egancies somehow */) {
agencies[i].nmbrEmp = number_employees;
agencies[i].employees = calloc(sizeof(agencies[i].employees[0]), number_employees);
// write agencies[i].employees[j] ...
}
Consider this Example :
struct Employee
{
char ename[20];
int ssn;
float salary;
struct date
{
int date;
int month;
int year;
}doj;
}emp1;
Accessing Nested Members :
Accessing Month Field : emp1.doj.month
Accessing day Field : emp1.doj.day
Accessing year Field : emp1.doj.year
Here is the Code pad which will demonstrate the above example
enter link description here
In c, you cannot have unnamed nested structures [otherwise, nested types]. They have to be a named structure. You need to write something like
typedef struct agency
{
char nom[20];
int nmbrEmp;
struct employee
{
char mat[20];
int nmbrEnf;
int ANC;
double SB;
double RCNSS;
} emp [20];
}agency;
However, here you are limited to the static input of a size 20, that means, you cannot have more than 20 employee records. To liberate from this limitation , the best approach is to use a pointer to an employee structure, an in runtime, allocate memory based on the number of the employee given by the user.
Here's an example you might consider. This is a template of what you have to do, you are left with manipulating employees, agencies name and so on. (Note that there's no error checking, which is bad.)
#include <stdio.h>
#include <stdlib.h>
/* TODO: modify members */
typedef struct {
int id;
int salary;
} employee;
/* TODO: modify members */
typedef struct {
char name[20];
employee* emps;
int emps_count;
} agency;
/* return sum of id and salary for first employee from agency */
int dumb_calc(agency ag) {
return ag.emps[0].id + ag.emps[0].salary;
}
int main(void)
{
int num_ag;
int num_emps;
int i, j;
printf("enter num of agencies:\n");
scanf("%d", &num_ag);
agency* agencies = malloc(sizeof(agency) * num_ag);
for (i = 0; i < num_ag; ++i) {
/* TODO: modify single agency name */
sprintf(agencies[i].name, "agency %d", i+1);
printf("enter num of employees for agency %d\n", i+1);
scanf("%d", &num_emps);
agencies[i].emps = malloc(sizeof(employee) * num_emps);
agencies[i].emps_count = num_emps;
for (j = 0; j < num_emps; ++j) {
/* TODO: modify single employee */
agencies[i].emps[j].id = j+1;
agencies[i].emps[j].salary = 1000*(j+1);
}
}
/* TODO: change printing style */
for (i = 0; i < num_ag; ++i) {
printf("agency name: %s\n", agencies[i].name);
printf("num of employees: %d\n", agencies[i].emps_count);
/* result will always be the same */
printf("sum of id and salary for 1st emp: %d\n", dumb_calc(agencies[i]));
}
/* remember to free what you've alloc'd */
for (i = 0; i < num_ag; ++i) {
free(agencies[i].emps);
}
free(agencies);
return 0;
}
Related
How can I pass the pointer to the structure to another function?
sample:
#include<stdio.h>
struct customer{
char name[50];
int number;
};
void input(){
struct customer details;
printf("enter your name: ");
scanf("%s",details.name);
details.number++;
printf("%d\t%s",details.number,details.name);
}
int main(){
struct customer details;
input();
//pcust->number++; how should I declare this?
printf("%d\t%s",details.number,details.name);
}
how do you automatically assign a number in a struct where I can call its value in other functions?
suppose I have this struct
struct customer{
char name[50];
int number;
};
and request input for the user
void input(){
struct customer details;
printf("enter your name");
scanf("%s",details.name);
printf("enter your number");
scanf("%d",&details.number);
}
instead of asking them to enter their number in the function to call it by value, how can I assign it automatically, so I can call it by its value? The possible output I need is like this so that in the next function again, I can call by its value again.
1 customer1
2 customer2
....
#include <stdio.h>
struct customer
{
char name[50];
int number;
};
void input(struct customer *pDetails)
{
printf("enter your name: ");
scanf("%s", pDetails->name);
pDetails->number++;
printf("%d\t%s \n", pDetails->number, pDetails->name);
}
int main()
{
struct customer details = {};
input(&details);
printf("%d\t%s \n", details.number, details.name);
}
Your main problem is that you do not use any function parameters.
You need to have some kind of search (for example if you want to modify a customer record
Use arrays to store multiple data.
Example:
struct customer
{
char name[50];
int somedata;
};
struct database
{
size_t size;
struct customer customers[];
};
struct customer *findCustomer(const struct database *db, const char *name)
{
struct customer *result = NULL;
if(db)
{
for(size_t i = 0; i < db -> size; i++)
if(!strcmp(db -> customers[i].name, name))
{
result = (struct customer *)&db -> customers[i];
break;
}
}
return result;
}
struct database *addCustomer(struct database *db, const char *name)
{
size_t newSize = db ? db -> size + 1 : 1;
db = realloc(db, newSize * sizeof(db -> customers[0]) + sizeof(*db));
if(db)
{
strcpy(db -> customers[db -> size].name, name);
}
return db;
}
I have a struct defined like this:
typedef struct {
char id[20];
char descrizione[250];
char tipoSet[30];
int scatoleDisponibili;
float costo;
} Set;
I have another struct called Complex in which I want a field to store an array of only Set struct IDs.
typedef struct {
char idComplesso[20];
content[10];
int dimLogica;
} complex;
So, I want the content array (of max size 10) to be able to store only the string id from a max of 10 Set.
How could I do this in C?
typedef struct {
char id[20];
char descrizione[250];
char tipoSet[30];
int scatoleDisponibili;
float costo;
} Set;
typedef struct {
char idComplesso[20];
int dimLogica;
size_t nsets;
char *content[];
} complex;
complex *assign(Set *s, size_t nsets)
{
complex *cml = malloc(sizeof(*cml) + nsets * sizeof(cml -> content[0]));
/* allocation check */
cml -> nsets = nsets;
for(size_t i = 0; i < nsets; i++)
{
cml -> content[i] = s[i].id;
}
return cml;
}
You'll have to make the content array be an array of char* and when you create the structure only accept id from a Set struct.
Something like this:
complex* createComplex(Set* sets) {
complex* comp = (complex*)malloc(sizeof(complex));
for (int i=0; i<10; i++) {
comp->content[i] = sets[i].id;
}
return comp;
}
And don't let any other function create the comp struct
very new to c. I wrote the following code.
typedef struct
{
char name[100];
int comp, math, phys;
int total;
} student[100];
int main(int argc, char** argv) {
int number;
do
{
printf("Enter how many students: ");
scanf("%d", &number);
if(number < 0)
{
printf("Wrong input! \n");
}
}
while(number < 0);
int i;
for(i=0; i < number; ++i)
{
printf("Student %d's name: ", i+1);
scanf("%s", student[i].name);
printf("Comp: " );
scanf("%d", &student[i].comp);
printf("Phys: " );
scanf("%d", &student[i].phys);
printf("Math: " );
scanf("%d", &student[i].math);
&student[i].total = &student[i].comp + &student[i].math + &student[i].phys;
}
printf("s%", &student[1].name);
return (EXIT_SUCCESS);
}
I keep getting error: expected expression before 'student' in all the scanf lines and the last printf line. What am I doing wrong? Very new to C so any help would be great.
Do
struct
{
char name[100];
int comp, math, phys;
int total;
} student[100];
If you want to combine the definition and identifier. You should know that student isn't a type, it's an array of structs without a name. There are alternatives to what you want to accomplish. For example:
typedef struct student
{
char name[100];
int comp, math, phys;
int total;
} student;
student students[100];
Drop the typedef keyword. You're wanting to create an array of 100 student objects, not a type name representing an array of 100 students.
Hopefully this helps you in the future:
// `Type var` is a shorter way to write `struct tag var`
// `Type` is just an alias (another name) for `struct tag`
typedef struct tag {
int x;
} Type;
// `Type100 arr` is a shorter way to write `struct tag100 arr[100]`
// `Type100` is just an alias for `struct tag100[100]`
// No, you can't do `struct tag100[100] arr`; `Type100 arr` gets around this restriction
typedef struct tag100 {
int x;
} Type100[100];
// `var` contains a single value of type `struct tagX`
struct tagX {
int x;
} var;
// `arr` is an array of 100 values of type `struct tagX100`
struct tagX100 {
int x;
} arr[100];
I have the following code in C:
typedef struct
{
int age;
int phoneNumber;
} Student;
typedef struct
{
int id;
int student[1];
} People;
#define NUM_OF_PEOPLE
void *p = malloc(sizeof(People) + sizeof(int) * NUM_OF_PEOPLE + sizeof(Student) * NUM_OF_PEOPLE);
How could I find the pointer to the memory point to the first element of struct Student in the memory?
I try to do it in the following way:
int i = 0;
for(i = 0; i < NUM_OF_PEOPLE; i++)
{
Student * student_p = p.student[NUM_OF_PEOPLE];
}
It does not work, so can we allocate memory in the way?
And how to find the first element of struct Student in the memory?
What you have is an ancient way of having a flexible array member, which was technically also undefined behavior.
You are looking for this.
First, you need to define your struct like this (I don't know what the ints before the Students are, so let's just call it id):
typedef struct
{
int age;
int phoneNumber;
} Student;
typedef struct
{
int id;
Student student;
} StudentAndId;
typedef struct
{
int id;
StudentAndId students[];
} People;
Note the lack of size in the array inside People. Now you do this:
People *p = malloc(sizeof(People) + sizeof(StudentAndId[NUM_OF_PEOPLE]));
Then you can access students inside p as if it was an array of NUM_OF_PEOPLE elements.
Remember to compile with C99 (or C11) support. With gcc that would be -std=c99 or -std=gnu99.
This will allocate memory for storing the date but how you access it depends on how you store date. using C pointers you can store and access data using this structure and allocation but accessing the members will not be direct. it will involve pointer arithmetic. So better to use other structure if possible. If using this way of allocation then you need to do pointer arithmetic to get the next elements.
Try this:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int age;
int phoneNumber;
} Student;
typedef struct
{
int id;
int student[1];
} People;
#define NUM_OF_PEOPLE 10
int main()
{
People *p = malloc(sizeof(People) + sizeof(int) * NUM_OF_PEOPLE + sizeof(Student) * NUM_OF_PEOPLE);
int* id = (int*)(p+1);
Student* s = (Student*)(id+NUM_OF_PEOPLE);
printf("Size of People : %d\n", sizeof(People));
printf("p points to : %p\n", p);
printf("id points to : %p\n", id);
printf("s points to : %p\n", s);
}
Here's a sample output:
Size of People : 8
p points to : 0x80010460
id points to : 0x80010468
s points to : 0x80010490
You may want to add the id field to your Student data structure, e.g.:
typedef struct {
int id;
int age;
int phoneNumber;
} Student;
Then, you can define a structure having a fixed header (in this case, this can be the number of students), followed by a variable-sized array of Students:
#define ARRAY_OF_ANY_SIZE 1
typedef struct {
int count;
Student students[ARRAY_OF_ANY_SIZE];
} People;
This blog post explains this technique of having "arrays of size 1", including a discussion of the alignment problem.
I won't repeat the original blog post code here. Just consider that you can use the portable offsetof() instead of the Windows-specific FIELD_OFFSET() macro.
As a sample code, you may want to consider the following:
#include <stdio.h> /* For printf() */
#include <stddef.h> /* For offsetof() */
#include <stdlib.h> /* For dynamic memory allocation */
typedef struct {
int id;
int age;
int phoneNumber;
} Student;
#define ARRAY_OF_ANY_SIZE 1
typedef struct {
int count;
Student students[ARRAY_OF_ANY_SIZE];
} People;
int main(int argc, char* argv[]) {
People* people;
const int numberOfStudents = 3;
int i;
/* Dynamically allocate memory to store the data structure */
people = malloc(offsetof(People, students[numberOfStudents]));
/* Check memory allocation ... */
/* Fill the data structure */
people->count = numberOfStudents;
for (i = 0; i < numberOfStudents; i++) {
people->students[i].id = i;
people->students[i].age = (i+1)*10;
people->students[i].phoneNumber = 11000 + i;
}
/* Print the data structure content */
for (i = 0; i < people->count; i++) {
printf("id: %d, age=%d, phone=%d\n",
people->students[i].id,
people->students[i].age,
people->students[i].phoneNumber);
}
/* Release the memory allocated by the data structure */
free(people);
return 0;
}
Output:
id: 0, age=10, phone=11000
id: 1, age=20, phone=11001
id: 2, age=30, phone=11002
I need to execute a function that returns array of a specified struct with variable length. Then I should loop through the returned array.
example struct :
typedef struct student {
int id;
char *name;
int grade;
} Student;
function prototypes 1 :
Student *students;
students = findStudentByGrade(int grade);
function prototypes 2 :
Student *students;
int retval = findStudentByGrade(&students, int grade);
I am bit confused on above methods. How can correctly define a array of struct? call function ? and loop through it untill end? Can some one help me please.
You can do this in this way. This code is working. I tested in CodeLite.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct student {
int id;
char *name;
} Student;
Student *findStudent(int *asize, const int grade);
int main(void)
{
Student *stds;
int asize = 0;
stds = findStudent(&asize, 5);
int i;
for (i = 0; i < asize; i++) {
printf("ID : %i\n", stds[i].id);
}
return 0;
}
Student *findStudent(int *asize, const int grade)
{
struct student *stds = malloc(sizeof(struct student) * 3);
stds[0].id = 10;
stds[1].id = 20;
stds[2].id = 40;
*asize = 3;
return stds;
}
Get the array of struc as returned statement and pass an int variable with argument list to get the size back and simply loop through using a for loop. Or else you will find problem in looping. It is more easy to get the array size from the function which create the array.
I mean this is quite a basic question, but:
Defining array of your structures would look like:
int size = ...;
Student *students = (Student*) malloc(sizeof(Student) * size);
Then just pass that to the function (both size and the array) and then just loop until i < size.
Ofcourse, don't forget to:
free(students);
at the end.