So I'm trying to learn how to use pointers in C and I want to make a struct that stores a random number of students and their names and ages. I'm trying my best to avoid pre-allocated static sized arrays, as I'm learning how to use pointers, and this is where I'm stuck.
I'm basically writing an application that asks for the n student's name and age, until the name given is stop
and stores the data in the struct (using a (ptr i)->studentName) and so on (Not that I've made the for loop yet).
Here is what I have come up with:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
struct student_t{
char studentName[30];
int age;
}student_t;
int main() {
struct student_t *ptr;
ptr = (struct student_t*) malloc(10 * sizeof(struct student_t));
printf("Type student information: ");
scanf(" [^%s] %i", ptr->studentName, &ptr->age);
char a[10] = "stop";
if(ptr->studentName == a){
//exit when this is true
}
else
printf("%s %i", student_t.studentName, student_t.age);
printf("Type student information: ");
scanf("%s %i", (ptr 1)->studentName, &(ptr 1)->age);
//keep asking this until the if statement above is true and so on (maybe make a for loop?)
}
I know i need a for loop somewhere with int i
but, yeah, I'm stuck.
Don't really know where i should use malloc() and realloc() either...
Any ideas?
CodePudding user response:
Read user input with fgets()
.
Use a generous sized buffer.
Use sscanf()
and various specifiers. E.g. "%n"
to record offset of the scan. %*s
scans for a word, but does not save.
Test input for sanity.
#define AGE_MIN 0
#define AGE_MAX 120
#define FNAME_SIZE 100
#define LNAME_SIZE 200
#define INT_SIZE 12
// first space last space number \n \0
char buffer[FNAME_SIZE 1 LNAME_SIZE 1 INT_SIZE 1 1];
printf("Type student information: ");
if (fgets(buffer, sizeof buffer, stdin)) [
int name1;
int name2;
// skip leading space
// Record offset
// scan a name
// scan a single space
// scan a name
// Record offset
// scan a int
if (sscanf(buffer, " %n%*s%*1[ ]%*s%n %d",
&name1, &name2, &ptr->age) == 1) {
if (ptr->age < AGE_MIN || ptr->age > AGE_MAX) {
// age issue
TBD_error_code();
}
// Test full name size
unsigned len = name2 - name1;
if (len >= sizeof ptr[j].studentName) {
// name too big
TBD_error_code();
}
memcpy(ptr[j].studentName, buffer name1, len);
ptr[j].studentName[len] = '\0';
printf("%s %i", student_t.studentName, student_t.age);
}
CodePudding user response:
So, I tried to find a way to help you, and got that.
You can use a while loop using the function strcmp(str1, str2)
as condition to exit, and an index i to navigate in ptr. Inside the loop, you can directly realloc the ptr.
int main()
{
struct student_t *ptr = malloc (sizeof(struct student_t));
char a[10] = "stop";
int i = 0;
// you can use a while loop with that condition.
while (strcmp(ptr[i - 1].studentName, a) != 0)
{
// condition that check if we can realloc or not.
ptr = (i != 0) ? (struct student_t*) realloc (ptr, sizeof(struct student_t) * (i 1)) : ptr;
printf ("Type student information: ");
scanf ("%s %i", ptr[i].studentName, &ptr[i].age);
i ;
// for loop to display ptr's information.
for (int j = 0; j < i; j )
{
printf ("%s %i \n", ptr[j].studentName, ptr[j].age);
}
}
free (ptr) ;
return 0;
}
(ptr i) is equivalent ptr[i]