2013-04-19 4 views
5

Эта программа должна захватывать входные данные от пользователя в структуру и затем распечатывать гистограмму данной информации. Пока все работает нормально, за исключением того, что когда я пытаюсь распечатать гистограмму, все символы «*» попадают под класс F независимо от уровня ученика. Я думаю, что происходит то, что индекс массива студента передается вместо самой фактической переменной, но я запутался, потому что в выводе перед печатью гистограммы отображается правильное значение. Какие-либо предложения?Доступ к элементам массива структуры

#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
displayHist(&studentRecords[students], students); 

&studentRecords[students] является адрес после вашего массива studentRecords. В displayHists доступ к records[i] будет пытаться разыменовать studentRecords[students+i], который находится за пределами вашего массива.

Корректный вызов может быть:

displayHist(&studentRecords[0], students); 

Что эквивалентен:

displayHist(studentRecords, students); 

Кстати, нет необходимости использовать & в scanf с char *, потому что char (*)[] и char * могут иметь разные представления памяти.

+1

Аааа! Lol спасибо, я должен был это знать. Я похлопываю себя по голове за эту ошибку LoL. Большое спасибо – KryptNick

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] 

При использовании адреса из, т.е. &, становится char **, который не то, что scanf ожидает.

Так что попробуйте использовать этот способ.

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

и

displayHist(studentRecords, students); 
+0

Обратите внимание, что это не становится 'char **'; он становится символом 'char (*) [28]' (указатель на массив из 28 символов), как указано в сообщении об ошибке. Вы правы, что это не то, что ожидает 'scanf()' (но, как ни странно, адрес прошел одинаково). –

Смежные вопросы