Home > Software design >  Using pointers to store information in a struct in C
Using pointers to store information in a struct in C

Time:11-04

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]

  • Related