1

The problem is to find the greatest average of a group of students. As you know Structure works here and to my point of view it's a good idea (Or maybe) that first make that structure using Array of Structure because I have for example 30 students. Then searching through the members of that structure and find the ultimate answer.

But I've encountered a problem which I can't fill the struct Stdinfo student[stdnum] and my for loop actually doesn't work correctly and I don't know why!

As a check I used printf() to print one of the members but I couldn't.

Here is my code :

#include <stdio.h>

struct Stdinfo
{
    char name[30];
    int score;
};

struct Stdinfo function();

int main(int argc, char **argv)
{
    //Number of students ~stdnum
    int stdnum, i;
    puts("Input numbers of student(s) :");
    scanf("%i", &stdnum);
    stdnum--;

    struct Stdinfo student[stdnum];

    //Filling array of structure
    for (i = 0; i < stdnum; i++)
    {
        student[i] = function();
    }

    return 0;
}

struct Stdinfo function()
{
    struct Stdinfo student;
    puts("Input the name of the student : ");
    fgets(student.name, sizeof(student.name), stdin);
    puts("Input his(her) score:");
    scanf("%i", &student.score);
    return student;
}

Now searching is not my main problem and I appreciate any help by which I can solve "Structure's members filing" problem.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
Pouyan
  • 363
  • 5
  • 22
  • 2
    Why did you subtract 1 from `stdnum`? Now your array is too small. – Barmar Sep 22 '17 at 08:39
  • @Barmar_ Because if you have 3 students you'll have array of size 2. 0,1,2 – Pouyan Sep 22 '17 at 08:40
  • 1
    No, that's size 3. The indexes go from 0 to size-1. – Barmar Sep 22 '17 at 08:41
  • 3
    One of your problems is that you mix `scanf`, which doesn't care about new-lines, and `fgets`, which reads entire lines. After you've scanned the number of students, the internal input marker sits right after the number, but before the new-line. `fgets` then reald an empty line. Use a two-step approach for your numbers: Read a line with `fgets` first and then extract the number with `sscanf` or `strtol`. – M Oehm Sep 22 '17 at 08:41
  • 3
    See https://stackoverflow.com/questions/5918079/fgets-doesnt-work-after-scanf for more explanation of what @MOehm just said – Barmar Sep 22 '17 at 08:43
  • @Barmar- If I am wrong please present the whole edited code to me. – Pouyan Sep 22 '17 at 08:43
  • @Pouyan if your `stdnum = 3` and your condition is `<` then the array will go `0,1,2`, however, if your condition is `<=` then the array will go `0,1,2,3`. And try using `fflush()`. – Strahinja Sep 22 '17 at 08:44
  • @StrahinjaRodic_ Yeah you're right. Thanks. – Pouyan Sep 22 '17 at 08:45
  • @StrahinjaRodic `fflush` is wrong here. – melpomene Sep 22 '17 at 08:46
  • Hrm... the question title is somewhat misleading. – Jabberwocky Sep 22 '17 at 08:46
  • @MichaelWalz- Yes I agree with you. I have problem with writing suitable title. Where can I read some hints ? – Pouyan Sep 22 '17 at 08:50

1 Answers1

0

You decrease the size of the array incorrectly. When doing so, you ignore the last student. Discard that decrement.

Now think how the input comes. The user enters the number of students and then his Enter!

scanf("%i" ,&stdnum); will consume the number, but not the newline (from Enter).

As a result, fgets() will read that newline and stop there. In others words, it thinks that this is what the input actually is. To alleviate this problem, simply consume this newline, e.g. with getchar(), before fgets() gets called.

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

struct Stdinfo{
        char name[30];
        int score;
    };

struct Stdinfo function() ;

int main(void)
{
    //Number of students ~stdnum
    int stdnum , i; 
    puts("Input numbers of student(s) :") ;
    scanf("%i" ,&stdnum);
    // Do not do that, it makes your program ignore the last student
    //stdnum--;

    struct Stdinfo student[stdnum]  ; 

    //Filling array of structure
    for(i=0 ; i < stdnum ; i++)
    {
        student[i] = function() ;
    }
    // print your array
    for(i=0 ; i < stdnum ; i++)
    {
        printf("%s\n", student[i].name);
        printf("%d\n", student[i].score);
    }

    return 0;
}

struct Stdinfo function() {

    struct Stdinfo student;

    getchar(); // Consume newline from previous input

    puts("Input the name of the student : ") ;
    fgets(student.name , sizeof (student.name) , stdin);
    // remove trailing newline from 'fgets()'
    student.name[strcspn(student.name, "\n")] = 0;

    puts("Input his(her) score:") ; 
    scanf("%i" ,&student.score) ;

    return student ; 
}

PS: You may want to Removing trailing newline character from fgets() input (my example does this).

gsamaras
  • 71,951
  • 46
  • 188
  • 305