0

I've been at this mess for a while and I still haven't figured out where I'm going wrong with it, totally knifing myself if it's something ridiculous like a pointer.

Task shown: Trying to fill a structure array with student ID, name, last name, date of birth, and grades.. Then search by a matching ID that's given to the user.

I'd highly appreciate any help related to this subject, I've been seriously stuck at it for a while. Also I apologize in advance for the french parts

// Part 1
struct Date{
    int day;
    int month;
    int year;
};

// Part 2
struct Student{
    int ID;
    char name[20];
    char lastname[20];
    struct Date DOB;
    int notes[J];
};

// Part 3
void FillStudentList(struct Student E){
    int i;
    printf("\nInsert ID: ");
    scanf("%d", &E.ID);
    printf("Insert name: ");
    scanf("%s", &E.name);
    printf("Insert last name: ");
    scanf("%s", &E.lastname);
    printf("Insert date of birth: ");
    scanf("%d %d %d", &E.DOB.day, &E.DOB.month, &E.DOB.year);
    printf("Insert notes: ");
    for(i=0; i<J; i++)
        scanf("%d", &E.Notes[i]);
}

// Part 4
void ShowByNb(int Nb, struct Student E[], int NbStudents){
    int j, i;
    for(i=0; i<NbStudents; i++){
        if (E[i].ID== Nb){
            printf("\nID: %d", E[i].ID);
            printf("\nName: %s", E[i].name);
            printf("\nLast Name: %s", E[i].lastname);
            printf("\nDate Of Birth: %s-%s-%s", E[i].DOB.day, E[i].DOB.month, E[i].DOB.year);
            printf("\nNotes: ");
            for(j=0; j<J; j++){
                printf("%d", E[i].Notes[j]);
            }
        }
        else
            printf("\nInvalid Student!\n");
    }
}

// Part 5
void main(){
    int i, x;
    struct Student E[N];
    for(i=0; i<N; i++){
        printf("\n\nStudent #%d", i+1);
        FillStudentList(E[i]);
    }

    printf("\n\nSearch student by NB: ");
    scanf("%d", &x);
    ShowByNb(x, E, N);
    } 
Patrick Younes
  • 139
  • 1
  • 15

2 Answers2

0

The edited code below, I believe, achieves your goal. The main problem (other than reading/printing 'int's with '%s' was how you pass your structure to your functions. It is necessary to pass the structure by reference so that its values can be seen outside of the FillStudentList function; see this link.

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

#define N 2
#define J 2

// Part 1
struct Dat{
    int jour;
    int mois;
    int annee;
};

// Part 2
struct Etudiant{
    int numero;
    char nom[20];
    char prenom[20];
    struct Dat DDN;
    int Notes[J];
};

// Part 3
/* Modified this so that a pointer to the struct is passed instead of a copy of the struct */
void FillStudentList(struct Etudiant *E){
    int i;
    printf("\nInsert ID: ");
    scanf("%d", &E->numero);
    printf("Insert name: ");
    scanf("%s", E->nom);
    printf("Insert last name: ");
    scanf("%s", E->prenom);
    printf("Insert date of birth: ");
    /* These are integers. Do not read with %s */
    scanf("%d %d %d", &E->DDN.jour, &E->DDN.mois, &E->DDN.annee);
    printf("Insert notes: ");
    for(i=0; i<J; i++)
        scanf("%d", &E->Notes[i]);
}

// Part 4
void ShowByNb(int Nb, struct Etudiant E[]){
    /* Don't redefine N == NbEtudiants making it seem that N is variable */
    int j, i;
    for(i=0; i<N; i++){
        if (E[i].numero == Nb){
            printf("\nID: %d", E[i].numero);
            printf("\nName: %s", E[i].nom);
            printf("\nLast Name: %s", E[i].prenom);
            /* Again, can't print integers with %s */
            printf("\nDate Of Birth: %d-%d-%d", E[i].DDN.jour, E[i].DDN.mois, E[i].DDN.annee);
            printf("\nLes notes: ");
            for(j=0; j<J; j++){
                printf("%d ", E[i].Notes[j]);
            }
            return;
        }
        /* Your previous else would print invalid student every time you ran through the loop even 
         * if the student number was valid for a later student.
         */
    }
    /* Only print this if student was not found in any of the N Student structures */
    printf("\nInvalid Student!\n");
}

// Part 5
void main(){

    setbuf(stdout, NULL);

    int i, x;
    struct Etudiant E[N];

    for(i=0; i<N; i++){
        printf("\n\nStudent #%d", i+1);
        FillStudentList(&E[i]);
    }

    printf("\n\nSearch student by NB: ");
    scanf("%d", &x);
    ShowByNb(x, E);
}

Input

1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2

Output

Student #1
Insert ID: 1
Insert name: 1
Insert last name: 1
Insert date of birth: 1
1
1
Insert notes: 1
1


Student #2
Insert ID: 2
Insert name: 2
Insert last name: 2
Insert date of birth: 2
2
2
Insert notes: 2
2


Search student by NB: 2

ID: 2
Name: 2
Last Name: 2
Date Of Birth: 2-2-2
Les notes: 2 2
Community
  • 1
  • 1
PZwan
  • 101
  • 2
  • 6
  • Thank you for the reply, but the problem persists. I tried doing it like that and I get the error " error C2232: '->nom' : left operand has 'struct' type, use '.' " – Patrick Younes Mar 31 '16 at 03:37
  • Can you try copying the exact code that I posted? It is working for me. I've updated the answer to include input and code output. – PZwan Mar 31 '16 at 03:54
  • @PZwan You code still has some errors. In `scanf("%s", &E->nom);` scanf is expecting a `char *` but you are using `char (*)[20]`. The same goes to `scanf("%s", &E->prenom);` It should be `scanf("%s", E->nom);` and `scanf("%s", E->prenom);` – SSC Mar 31 '16 at 05:45
  • @SSC Thanks. I made the changes. – PZwan Mar 31 '16 at 12:22
0

classic mistake: passing parameter by value instead of by reference:

void FillStudentList(struct Student E){
.....
}

What happens here is that a local copy of your structure is created on the stack, populated with whatever the input is and destroyed when the function exits.

Generally in C, even if you don't want to modify the structure, you pass struct parameters by pointer; if you pass them by value each member of the structure is copied on to the stack...which is a waste of time an memory.

So changing the function prototype (and the code to work with the new signature) should fix the issue:

void FillStudentList(struct Student *E){
....
}
Pandrei
  • 4,843
  • 3
  • 27
  • 44