0

I want to call a function to fill in the values of a struct in C. I have the following code but I get errors like [Error] request for member 'id' in something not a structure or union.

#include <stdio.h> 

typedef struct {
    int       id;
    float    grades[3];
} student_t;

void scan_student (student_t *s) {
    printf("Please give student's info:\n");
    scanf("%d%f%f%f", s.id, s.grades[0], s.grades[1], s.grades[2]);
}

int main () 
{ 
    student_t stu2;

    scan_student(&stu2);

    printf("Student's info are:\n");
    printf("%6d %5.2f %5.2f %5.2f\n", stu2.id, stu2.grades[0], stu2.grades[1], stu2.grades[2]);

    return 0; 
} 
5
  • try this - &s.id Commented Nov 15, 2018 at 13:33
  • 2
    And... you should have tons of warnings here. The rule says: warnings are not to be ignored (at least unless you understand why the warning and why you can ignore it in that special use case) Commented Nov 15, 2018 at 13:37
  • @OldProgrammer - OP hasn't even got to that error yet! Commented Nov 15, 2018 at 14:39
  • 1
    Another thing is... use English, at least English identifiers (if your audience really does not know "grade"). As you realize right here, this is a global world. In modern languages like C# I suppose you could even use Greek identifiers, and certainly Greek strings (this web application allows me to write βαθμός) -- don't do that. Stick to 7 bit ASCII, English and 80 character lines unless there is a compelling reason not to. Commented Nov 15, 2018 at 14:44
  • 1
    @PeterA.Schneider Yes, you are absolutely right! I'm sorry. I fixed the text. Commented Nov 16, 2018 at 9:20

2 Answers 2

9

s is a pointer, not a struct. That means you can't use . on it.

Instead you have to write (*s).id (dereference, then access struct member) or s->id (same thing, but shorter).

Also, scanf %d takes a pointer, so that should be &s->id, etc.

Sign up to request clarification or add additional context in comments.

Comments

0

I also post an example without using pointers:

#include <stdio.h> 

typedef struct {
    int       id;
    float    grades[3];
} student_t;

student_t scan_student () {
    student_t s;
    printf("Please give patient's info:\n");
    scanf("%d%f%f%f", &s.id, &s.grades[0], &s.grades[1], &s.grades[2]);
    return s;
}

int main () 
{ 
    student_t stu2;

    stu2= scan_student();

    printf("Student's info are:\n");
    printf("%6d %5.2f %5.2f %5.2f\n", stu2.id, stu2.grades[0], stu2.grades[1], stu2.grades[2]);

    return 0; 
} 

3 Comments

Passing stu2 to scan_student as an argument is pointless in your example.
@FiddlingBits Has a good point. You can as well return a local variable (note: by value! returning pointers to locals is, of course, wrong); no need to pass anything as a parameter to the function. The way it is now means the following: (1) Create a local copy of the parameter (note: this is why you could as well use a local variable right away); (2) fill that; (3) return a temporary copy of the local variable on the stack; (3) copy that temporary back into stu2, overwriting whatever uninitialized values were present there.
I realize that I have two third steps in my above comment ;-). Oh well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.