5

This program is supposed to capture input from the user into the struct and then print out a histogram of the given information. Everything works fine so far except that when I try to print the histogram all the '*' characters fall under the F grade no matter what the student's grade. What I think is happening is that the student's array index is being passed instead of the actual variable itself, but I'm confused because in the output before the histogram is printed it shows the correct value. Any suggestions?

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 28
#define MAXGRADE 100

struct studentData{
    char studentID[MAXSIZE];
    char studentName[MAXSIZE];
    int examPercent;
} studentRecords[MAXSIZE];

// function prototype for histogram
void displayHist(struct studentData *records, int classSize);

int main()
{
    int i, students = -1;
    //struct studentData *studentRecords[MAXSIZE];
    while(students < 0 || students > MAXSIZE)
    {
        printf("Please enter the number of students in your class:\n");
        scanf("%d", &students);

        if(students > MAXSIZE || students <= 0)
        {
            printf("Try again..\n");
            scanf("%d", &students);
        }

    }

 for(i=0;i<students;i++) {

        printf("Please enter the student #%d's lastname:\n", i+1);
        scanf("%s", &studentRecords[i].studentID);


        printf("Please enter the student #%d's ID#:\n", i+1);
        scanf("%s", &studentRecords[i].studentName);

        printf("Please enter the student's exam percent:\n");
        scanf("%d", &studentRecords[i].examPercent);

 }

 //This is just here to view the input...
 for(i=0;i<students;i++) {

        printf("Student #%d's name is %s\n", i+1, studentRecords[i].studentName);
        printf("student #%d's ID#:%s\n", i+1, studentRecords[i].studentID);
        printf("student #%d's grade was %d\n", i+1, studentRecords[i].examPercent);

  }

    displayHist(&studentRecords[students], students);

    return 0;
}

void displayHist(struct studentData *records, int classSize)
{
    int i;


       printf("A:");
    for(i=0;i<classSize;i++)
    {

        if(records[i].examPercent >=90)
        {
            printf("*");
        }

    }


       printf("\n");
       printf("B:");
    for(i=0;i<classSize;i++)
    {
        if(records[i].examPercent< 90 && records[i].examPercent >= 80)
        {
            printf("*");
        }
    }

       printf("\n");
       printf("C:");
     for(i=0;i<classSize;i++)
     {
        if(records[i].examPercent < 80 && records[i].examPercent >= 70)
        {
            printf("*");
        }

    }

   printf("\n");
   printf("D:");
   for(i=0;i<classSize;i++)
    {
        if(records[i].examPercent< 70 && records[i].examPercent >= 60)
        {
            printf("*");
        }

    }

   printf("\n");
   printf("F:");
   for(i=0;i<classSize;i++)
    {
        if(records[i].examPercent < 60)
        {
            printf("*");
        }

    }
}

2 Answers 2

2
displayHist(&studentRecords[students], students);

&studentRecords[students] is an address after your array studentRecords. In displayHists, accesses to records[i] will try to dereference studentRecords[students+i], which is outside the bounds of your array.

A correct call could be:

displayHist(&studentRecords[0], students);

Which is equivalent to:

displayHist(studentRecords, students);

By the way, no need to use & in scanf with char *, because char (*)[] and char * may have different memory representations.

1
  • 1
    Aaaa! Lol thanks I should have known that. I'm slapping myself on the head for that mistake LoL. Thanks so much
    – KryptNick
    Commented Apr 19, 2013 at 17:48
0
scanf("%s", &studentRecords[i].studentID);

scanf("%s", &studentRecords[i].studentName);

warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[28]’ [-Wformat]

When you use address-of, i.e. &, it becomes char **, which is not what scanf expects.

So try using this way.

scanf("%s", &(*studentRecords[i].studentID));

and

displayHist(studentRecords, students);
1
  • Note that it doesn't become char **; it becomes char (*)[28] (a pointer to an array of 28 characters), exactly as the error message states. You're right that it isn't what scanf() expects (but, curiously enough, the address passed is the same). Commented Apr 19, 2013 at 18:30

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.