Reputation: 1632
I've got a task to get no. of students, get their name and marks and output the students which has average over 85.
The problem: After I enter blabla 99 98 95 90
, I don't get the appropriate message. what I get is just some kind random of average instead. I mean, Print_One()
isn't executed after that input. (Failing to print the average above 85)
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
typedef struct {
char *name;
int marks[4];
float avg;
} student;
student *Create_Class(int);
void Avg_Mark(student*);
void Print_One(student*);
void exStudents(student *s, int size);
int main() {
int size, i;
student *arr;
printf("\nEnter the number of students: \n");
scanf("%d", &size);
arr = Create_Class(size);
exStudents(arr, size);
for (i = 0; i < size; i++)
free(arr[i].name);
free(arr);
getch();
}
student *Create_Class(int size) {
int i, j;
int idStud, nameStud, markStud;
student *classStudent;
classStudent = (student*)malloc(size * sizeof(student));
for (i = 0; i < size; i++) {
classStudent[i].name = (char*)malloc(51 * sizeof(char));
int numOfmarks = 4;
int sizeOfName;
printf("Please enter your name: \n");
flushall();
gets(classStudent[i].name);
sizeOfName = strlen(classStudent[i].name);
/*
if (classStudent[i].name > 50) {
classStudent[i].name = realloc(classStudent[i].name, 51);
classStudent[i].name[51] = '\0';
} else {
classStudent[i].name = realloc(classStudent[i].name, sizeOfName + 1);
}
*/
printf("Please enter 4 marks: ");
for (j = 0; j < numOfmarks; j++) {
scanf("%d", &classStudent[i].marks[j]);
}
Avg_Mark(&classStudent[i]);
}
return classStudent;
}
void Avg_Mark(student *s) {
int i, numOfMarks = 4, sum = 0;
for (i = 0; i < numOfMarks; i++) {
sum += s->marks[i];
}
s->avg = (sum / 4.0);
}
void Print_One(student *s) {
printf("The average of %s is %f", s->name, s->avg);
}
void exStudents(student *s, int size) {
int flag = 1;
while (size > 0) {
if (s->avg > 85) {
Print_One(s);
flag = 0;
}
s++;
size--;
}
if (flag)
printf("\n There're no students with above 85 average.");
}
Upvotes: 2
Views: 183
Reputation: 12779
If your input is like this:
1
blabla
99 98 95 90
The first newline after 1 is still in the input buffer when your program reaches get
, so an empty line is read and then the scanf
s will fail.
An easy fix could be to read the first number using this format:
scanf("%d ", &size);
// note ^ the space will consume the newline
But, as @chqrlie pointed out, "it will continue to read bytes from stdin until it sees one that is not whitespace. This will require the user to respond to the next question before the prompt is written."
A better idea is to read the name using another scanf
, but limiting the maxium number of chars read to the allocated size and adding a space at the beginning of the format string to consume all pending whitespaces:
// read max 50 char till a newline and extract the rest of line without storing it
scanf(" %50[^\n]%*[^\n]", classStudent[i].name);
// ^^^ a space at the beginning will also consume trailing spaces or newline
Upvotes: 2
Reputation:
It worked for me. All i did was using
_flushall();
instead of
flushall();
Upvotes: 1