Ok firstly I'll explain my assignment. For this assignment I have to use dynamic memory allocation which I am having no problems with. What I am having a problem with is figuring out the correct way to work my assignment. For my assignment I need to create a program that prompt the user to enter how many students they have then ask for the following information; Student ID, Birthdate, and Phone number. I need to use a loop to prompt the user to enter all the students information. I need to create a loop that will scan through all the student IDs and find the oldest student using their birthdate (The loop must be able scan through more then 3 students).
Here is my code, I havent done much in it yet because I'm not sure really where to start. I've already setup the dynamic memory allocation, but I don't know how to work the rest of this. Please help me.
Thank you.
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
int * studentData= NULL;
int students;
printf("How many students are you entering records for:\n");
scanf("%d", &students);
studentData=(int*)malloc((sizeof(int)*students));
}
You could define a structure:
//Define a type, such as int, char, double...
typedef struct studentDataType {
int ID;
int birthDateDay;
int birthDateMonth;
int birthDateYear;
int phoneNumber;
};
Then create an array, where each of those elements is of type studentData:
//Create an array, where each element is of type studentData
studentDataType *studentData = (studentDataType *)malloc(numberOfStudents * sizeof(studentData));
Then loop through them with:
for (int i = 0 ; i < numberOfStudents ; ++i) {
printf("%i %i %i\n", studentData[i].ID, studentData[i].phoneNumber);
}
Use the following struct. You can make year, month and day as separate fields. It will be simpler for a quick start:
struct Student
{
int studentID;
int year;
int month;
int day;
long long phone; // phone is too large for 32 int
};
Related
#include <string.h>
#include <stdio.h>
struct student{
char last[25] ;
char first[25];
};
struct seating {
struct student **seat;
};
//Set the first and last name to default values
void student_init_default(struct student *s ) {
strcpy(s->last_name,"***");
strcpy(s->first_name,"***");
}
void seating(int rowNum, int columnNum, struct seating *a ){
//Instantiate a 2D array specfied by the parameters
struct student students[rowNum][columnNum];
a->seat = students;
//Initialize each element to the default
for(int rows = 0; rows < rowNum; rows++){
for(int columns = 0; columns < columnNum; columns++){
student_init_default(&students[rows][columns]);
}
}
}
void main() {
struct seating room;
struct student student;
int row, col, rowNum, columnNum;
char student_info[30];
// Ask a user to enter a number of rows for an classroom seating
printf ("Please enter a number of rows for an classroom seating.");
scanf ("%d", &rowNum);
// Ask a user to enter a number of columns for an classroom seating
printf ("Please enter a number of columns for an classroom seating.");
scanf ("%d", &columnNum);
// seating
seating(rowNum, columnNum, &room);
}
To start off, I am a beginner at C. My problem is using pointers. The main point in this code is to make a 2D array of the struct student and then fill in the array by setting the default as first and last name. What Im asking for is if someone can give a easy explanation or hints on how to connect the parameter, struct classroom_seating *a, with struct student **seating, along with the 2D array. Along with that, how would I use struct classroom_seating *a to access the 2D array? I do know the basics of pointers but I've been researching for hours and haven't found a connection to work.
I do know that this line printf("%s", listOfStudents[0][2].firstName); prints *** (assuming the user entered 3,3 for row/columns). It's that I don't know how I would be able to access that in later methods.
a->seat = students;
The compiler is explicit about the error
error: cannot convert 'student [rowNum][columnNum]' to 'student**' in assignment
a->seat = students;
^
is wrong because here you are assigning a 2d array to a double pointer. 2d array decayed into struct student (*)[] and then you tried to assign it to struct student **.
Instead you should create the jagged array yourself and work with it.
a->seat = malloc(sizeof(struct student*)* rowNum);
if(!a->seat){
perror("malloc");
exit(EXIT_FAILURE);
}
for(int i = 0; i< rowNum; i++){
a->seat[i] = malloc(sizeof(struct student)* columnNum);
if(!a->seat[i]){
perror("malloc");
exit(EXIT_FAILURE);
}
}
After that you can pass the address of each struct student instance like you did and make changes to it.
To clarify further about the organization that you are likely to follow
struct seating room; Here room is a structure instance containing a double pointer. That's it. That pointer points to no where significant. It contains indeterminate value (garbage value).
Now you want to allocate some memory and work with it. That is being done in the function seating. As it is just a pointer, you allocate memory of rowNum struct student * and why struct student*? Because that in turn will point to a series of struct student variable instance.
After successful allocation, now you have the memory and it is not of automatic storage duration - it will stay when the function seating ends also. It's storage duration extends beyond the scope of the function.
Notice one thing, strcpy(s->last_name,"***"); but there is no last_name variable in the structure definition. It would be last. Same goes with other member variable also.
After making the changes you would pass the instance of struct student like this:-
for(int rows = 0; rows < rowNum; rows++){
for(int columns = 0; columns < columnNum; columns++){
student_init_default(&a->seat[rows][columns]);
}
}
You are trying to assign to a->seat something that does not fit(not possible). But even if it would fit it would be wrong as struct student students[rowNum][columnNum]; is defined locally to the function seating(), so the moment the code returned from this function all memory a->seat pointed to would have become invalid. Accessing it would be undefined behavior then. (alk pointed this).
typedef struct
{
int k;
union
{
int i;
int j;
}use;
}std;
Directly we can use the variable i and j in structure why it is used within union.
In your example, i.e.
typedef struct
{
int k;
union
{
int i;
int j;
}use;
}std;
it doesn't seem to make much sense as i and j are the same type and the names of the variables isn't that descriptive.
It can make sense to have the same type for union elements if that would make the code easier to write, read, understand and maintain. Example:
...
union
{
int numberOfCars;
int numberOfBicycles;
}use;
...
When writing code for handling cars you could use numberOfCars and when writing code for handling bicycles you could use numberOfBicycles. In this way the code would be easier to understand/maintain and the two code blocks could still share a common structure.
In one code block you could have:
std carDealer;
carDealer.use.numberOfCars = 9;
and in another code block (other file perhaps), you could have:
std bicyclesDealer;
bicyclesDealer.use.numberOfBicycles = 9;
A more typical case for unions is that the elements are of different type.
Suppose we wish to store information about employees in an organization.
Name Grade Age
If grade=HSK(Highly skilled)
hobby name
credit card number
If Grade=SSK(Semi skilled)
Vehicle no.
Distance from Company
We can use a single structure for it but then it would lead to wastage of memory coz either hobby name & credit card no. or vehicle no. & distance from com. is used at a time. Both of them are never used simultaneously. So, here union inside structure can be used effectively:
Code:
struct info1
{
char hobby[10];
int crcardno;
};
struct info2
{
char vehno[10];
int dist;
};
union info
{
struct info1 a;
struct info2 b;
};
struct emp
{
char n[20];
char grade[4];
int age;
union info f;
};
struct emp e;
HOPE YOU UNDERSTAND.......
Source : http://cboard.cprogramming.com/c-programming/122228-union-inside-structure.html
Hi I am trying to create a structure inside a structure, the first structure will contain details for a number of students, the second structure will contain details of a number of modules from each student. Each time asking the user to input details for each student. I was able to create an instance of student structure called data and each time loop through each instance of data and scan in information for each student once only that worked for me. I am now trying to create another inside loop that will scan in a number of different modules that will assign these to each student. I am having problems with the second loop and would appreciate some guidance.
struct module{
char moduleid[5];
int credit;
float grade;
};
//create structure student at includes a datatype
//module
struct student{
char id[10];
char fname[15];
char lname[15];
struct module results;
};
int main()
{
int i;
int j;
int numStuds;
int numMods = 10;
printf("Enter number of students\n");
scanf("%d",&numStuds);
struct student data[numStuds]; //create an instance of structure student called data
struct data.results mods[numMods];
//input data
for (i=0; i<numStuds; i++){
printf("PLEASE ENTER STUDENT DATA :\n\nID, FNAME AND LNAME\n");
scanf("%s%s%s",data[i].id,data[i].fname,data[i].lname);
for (j=0; j<numMods; j++){
printf("\nENTER MODULE DATA: \nMODULEID, CREDIT, GRADE :\n");
scanf("%s%d%f",data[i].results.mods[j].moduleid,&data[i].result.smods[j].credit,&data[i].results.mods[j].grade);
}
}
I think that your main problem is that in the way you have declared "results" inside your student struct you can only have one result for each student. Try to use an static array (if you know how many results you have) or a dynamic one if you want to declare its size during runtime.
e.g
struct student{
char id[10];
char fname[15];
char lname[15];
struct module *results; //Pointer to declare a dynamic array
};
For static declaration
struct student{
char id[10];
char fname[15];
char lname[15];
struct module results[size]; //Pointer to declare a dynamic array
};
If you use the pointer solution remember to access that attribute using "->" operator
Like acostela said, you might want a pointer to a dynamic array. However, I do not see why each student needs multiple results. So when you have the number of students entered, you would just know that each student had one module, referred to as data.result or data->result if you used malloc. If you really need dynamic arrays, I can show you some macros to do this easily.
Okay. I will just show you creation and deletion macros, you can do expansion, inserting, and deleting with realloc and memmove; it would take me too long to write them all out.
#include <stdint.h>
#define ARRAY_DECL(name, type) struct { uint32_t count; type *array } name;
#define ARRAY_DESTROY(name) free(name.array);
These macros create what is called an anonymous structure; this means that it is a one-of-a-kind struct, in this case called name. ARRAY_DESTROY then frees the array inside the struct.
I've recently been introduced to struct and in experimenting, I encountered a problem that I can't seem to find a solution for.
I want to create a structure with several members but I want the names for each member to be automatically generated to avoid tedious process of doing this manually. So far I have my structure and a function which I want to use to create a member.
STRUCT
struct Customers
{
char name[30];
int age;
}
PROTOTYPE
void newCustomer(Customers *Customer);
FUNCTION
void newCustomer(Customers *Customer)
{
char gender;
int age;
scanf_s("%c", 1, &gender);
scanf_s("%d", &age);
Customer->gender = gender;
Customer->age = age;
}
MAIN
int main()
{
int noOfCustomers;
int i = 0;
printf("How many customers will you be entering? : ");
scanf_s("%d", &noOfCustomers);
for(i = 0; i < noOfCustomers; i++)
{
Customers i;
newCustomer(&i);
}
return 0;
}
Basically I want to do something like this... where each member is automatically represented by an ID or number. I do understand that the above example won't work because i is being declared locally within the loop as a sructure member and not an int but I want to know if there is a method of achieving this.
Thanks in advance for any help :)
You can use static integer variable, call itoa to convert it to string, and then, increment.
Ok firstly I'll explain my assignment. For this assignment I have to use dynamic memory allocation which I am having no problems with. What I am having a problem with is figuring out the correct way to work my assignment. For my assignment I need to create a program that prompt the user to enter how many students they have then ask for the following information; Student ID, Birthdate, and Phone number. I need to use a loop to prompt the user to enter all the students information. I need to create a loop that will scan through all the student IDs and find the oldest student using their birthdate (The loop must be able scan through more then 3 students).
Here is my code, I've gotten some suggestions and even bits of code from you guys, but after implementing them I'm even more confused on what I should do. Please take a look at it and critique me.
EDIT: I also added in on the code where I'm receiving and error
Thank you.
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
int * studentData= NULL;
int * studentDataType=NULL;
int students;
int studentID;
int year;
int month;
int day;
long long phone;
printf("How many students are you entering records for:\n");
scanf("%d", &students);
studentData=(int*)malloc((sizeof(int)*students));
struct studentDataType
{
int studentID;
int year;
int month;
int day;
long long phone;
};
//invalid operands to binary * (have 'int' and 'int *')
studentDataType *studentData = (studentDataType*)malloc(numberOfStudents *sizeof(studentData));
for (int i = 0 ; i < students ; ++i)
{
printf("%d, %d, %d, %d, %d\n", studentID, year, month, day, phone);
}
}
You're redefining studentData
int * studentData= NULL;
then later
studentDataType *studentData = (studentDataType*)malloc(numberOfStudents * sizeof(studentData));
You should declare the studentDataType struct first (outside of main() ) then use it in your original declaration
To see the task it is better at least for the first time to write some block-scheme of what you have to do in a program. In your case:
Read data from user (each structure).
Increase array size, add new structure.
Loop 1-2 until input user finish adding new people (needs some condition here to finish).
Find necessary structure and print it.
So the first step is to read information from user. You can use scanf():
In the simplest way you can do that step-by-step for each field:
#include <stdio.h>
...
int value;
scanf("%d", &value);
...
In case of success this function should return number of items it reads (1 in your case).
For phone you should use scanf("%ld", &phone).
To resize array use function realloc() (#include :
realloc(&ptr_to_array, new_size);
Each elements of the array is a pointer to structure "student".
Next steps are similar.
The first problem is that you have variable names the same as the name of the type. Although you can have that in C to a certain extent, like:
typedef int x;
x foo (x x)
{
return x;
}
It might be a good idea not to do this for the readability purposes. So in your case you have:
int * studentData= NULL;
int * studentDataType= NULL;
which is a variable name, then you have:
struct studentDataType ...
which is a name of the type (should be used as struct studentDataType, not without struct as you do); finally
studentDataType *studentData = ...
is treated by the compiler as an operation on two variables, not a type declaration as you would expect. So your memory allocation needs to be:
struct studentDataType *studentData = malloc(numberOfStudents *sizeof(struct studentData));
Which brings a problem that you redefine studentData, which you declared in the beginning of the program, and "numberOfStudents" is not defined, probably you wanted to write "students" instead.
As for the reading data with scanf, see the previous comment.