Question

I am trying to pass a structure into a function that will print the contents. I am asking for any sort of tips or advice.

The struct

struct student
{
    char *fname;
    char *lname;
    float score;
};

Create prototype

void printStudents(struct student **s, int student_size);

Main Function

int main()
{
    int base_number, i;
    int students;

    struct student *ptr;

    printf("Enter Number of Students: ");
    scanf("%d", &base_number);
    ptr = (struct student*)malloc(base_number * sizeof(struct student));
    students = base_number;

    printf("\nEnter Student Information\nExample: John Smith 98.50\n\n");

    for(i = 0; i < base_number; i++)
    {
        printf("Student %d: ", i+1);
        scanf("%s %s %f", &(ptr+i)->fname, &(ptr+i)->lname, &(ptr+i)->score);
    }

    printStudents(&ptr, students);

    return 0;
}

printStudents Function

void printStudents(struct student **s, int student_size)
{
    int i;
    struct student *temp = (struct student*)malloc(student_size * sizeof(struct student));

    for(i = 0; i < student_size; i++)
        printf("%s %s %.2f\n", (temp+i)->fname, (temp+i)->lname, (temp+i)->score);
}
Was it helpful?

Solution 2

The structure members fname and lname are pointers to characters, not character arrays. Therefore, the scanf call

scanf("%s %s %f", &(ptr+i)->fname, &(ptr+i)->lname, &(ptr+i)->score);

is wrong and invokes undefined behaviour. You need to make those members as arrays.

#define MAX_LEN 40

struct student
{
    char fname[MAX_LEN];
    char lname[MAX_LEN];
    float score;
};

Also, when you pass an array to a function, it decays into a pointer to its first element. You should not use the address of operator & on it. Do not cast the result of malloc. Why do you allocate memory in the printStudents function? It causes memory leak as you don't free it. Also, the function parameter s does not need to be struct student ** type. I suggest the following changes -

#include <stdio.h>
#include <stdlib.h>

#define MAX_LEN 40

struct student
{
    char fname[MAX_LEN];
    char lname[MAX_LEN];
    float score;
};

void printStudents(struct student *s, int student_size);

int main(void)
{
    int base_number, i;
    int students;

    struct student *ptr;

    printf("Enter Number of Students:\n");
    scanf("%d", &base_number);
    ptr = malloc(base_number * sizeof *ptr);
    students = base_number;

    printf("\nEnter Student Information\nExample: John Smith 98.50\n\n");

    for(i = 0; i < base_number; i++)
    {
        printf("Student %d:\n", i+1);
        scanf("%s%s%f", (ptr+i)->fname, (ptr+i)->lname, (ptr+i)->score);
    }

    printStudents(ptr, students);
    free(ptr);

    return 0;
}

void printStudents(struct student *s, int student_size)
{
    int i;
    for(i = 0; i < student_size; i++)
        printf("%s %s %.2f\n", 
               (s+i)->fname, 
               (s+i)->lname, 
               (s+i)->score);
}

OTHER TIPS

  1. Is there any requirement to pass the pointer to a pointer? Couldn't you pass ptr directly??

  2. Why building another array temp?? it's just waste of memory..

.

void printStudents(struct student *s, int student_size);

..

printStudents(ptr, students);

...

void printStudents(struct student *s, int student_size)
{
    int i;

    for(i = 0; i < student_size; i++)
        printf("%s %s %.2f\n", s[i].fname, s[i].lname, s[i].score);
}

For printing the contents you need not to create another structure inside function. Use single pointer, no need of double pointer. Call the function using printStudents(ptr, students);

void printStudents(struct student *s, int student_size)
{
int i;
for(i=0;i<student_size;i++)
printf("%s %s %.2f\n", (s+i)->fname, (s+i)->lname, (s+i)->score);
}

I think there is a bug in your code.

struct student
{
    char *fname;
    char *lname;
    float score;
};

This define has problem, you don't allocate memory for fname and lname, but you store character arrat in these variable. Maybe you can use:

   struct student
    {
        char fname[20];
        char lname[20];
        float score;
    };

The second bug: when you use scanf to read string, just need this:

scanf("%s %s %f", (ptr+i)->fname, (ptr+i)->lname, &(ptr+i)->score);

The following code will work. The prototype should also be modified. The memory should be allocated only once.

void printStudents(struct student *s, int student_size)
{
    int i;
    //struct student *temp = (struct student*)malloc(student_size * sizeof(struct student));

    for(i = 0; i < student_size; i++)
        printf("%s %s %.2f\n", (student +i)->fname, (student +i)->lname, (student +i)->score);
}

The following statement allocates a new set of memory which does not have the old input data and should be avoided.

struct student *temp = (struct student*)malloc(student_size * sizeof(struct student));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top