Reputation: 3
#include <stdio.h>
#include <stdlib.h>
struct student
{
char name[30];
char dob[30];
int rollno;
float percent;
int sub[3];
int total;
};
int main(void)
{
int i, n,a,c,*ptr;
char ch;
struct student *st;
printf("Enter number of students data you want to enter:\n");
scanf("%d",&n);
st=(struct student*) malloc(n * sizeof(struct student));
if(st == NULL)
{
printf("Error! memory not allocated.");
exit(0);
}
for(i=1;i <= n;i++)
{
printf("Enter name of student %d\n",(i));
scanf("%s",&(st+i)->name);
printf("Enter Roll No of student %d\n",(i));
scanf("%d",&(st+i)->rollno);
printf("Enter Date Of Birth of student %d\n",(i));
scanf("%s",&(st+i)->dob);
printf("Enter marks for 3 subjects of student %d\n",(i));
scanf("%d %d %d",&(st+i)->sub[0],&(st+i)->sub[1],&(st+i)->sub[2]);
(st+i)->total = ((st+i)->sub[0]+(st+i)->sub[1]+(st+i)->sub[2]);
printf("Total Marks of student %d = %d\n\n",(i), (st+i)->total);
}
printf("\n");
printf("\n<1>To display details of students\n");
printf("\n<2>exit\n");
printf("Enter your choice:\n");
scanf("%c",&ch);
switch(ch)
{
case '1':
{
for(i=1; i <= n;i++)
{
printf("\n%d.%s",(st+i)->rollno,(st+i)->name);
}
printf("\n Enter Roll no to display info of student");
scanf("%d",&a);
{
c=a;
a=i;
i=c;
if((st+i)->sub[0]<33||(st+i)->sub[1]<33||(st+i)->sub[2]<33)
{
printf("\nName of student: %s",(st+i)->name);
printf("\nRoll No of student: %d",(st+i)->rollno);
printf("\nDate of Birth : %s",(st+i)->dob);
printf("\nTotal of student: %d",(st+i)->total);
printf("\nStudent Status fail");
return 0;
}
printf("\nName of student: %s",(st+i)->name);
printf("\nRoll No of student: %d",(st+i)->rollno);
printf("\nDate of Birth : %s",(st+i)->dob);
printf("\nTotal of student: %d",(st+i)->total);
(st+i)->percent=((st+i)->total)/3;
printf("\nPercent of Student = %f",(st+i)->percent);
if((st+i)->percent>=33)
{
printf("\nStudent status:- PASS\n");
}
else
printf("\nStudent status:-FAIL\n");
if((st+i)->percent>=90)
printf("Grade= A1\n");
else if (80<=(st+i)->percent)
printf("Grade= A2\n");
else if(70<=(st+i)->percent)
printf("Grade= B1\n");
else if(60<=(st+i)->percent)
printf("Grade= B2\n");
else if(50<=(st+i)->percent)
printf("Grade= C1\n");
else if(40<=(st+i)->percent)
printf("Grade= C2\n");
else if(33<=(st+i)->percent)
printf("Grade= D\n");
else if((st+i)->percent<33)
printf("Grade= F\n");
}
break;
}
case '2':
{
return 0;
}
default:
printf("Invalid! Try again...\n");
}
free(st);
return 0;
}
I want my program to take input of various details of students and display them when I enter the roll no. of student. However, the switch statement is not executing; the program just exits after taking input. I checked syntax, but it's correct I don't know what the issue is. If I could get a hint about the issue it would be great.
Upvotes: 0
Views: 130
Reputation: 3812
The problem has nothing to do with the switch
statement, but with writing to and reading from to correct memory locations.
In C, arrays start at index 0. Therefore, the first for-loop tries to access memory outside of what is allocated. The idiomatic solution is to start i
at 0 and loop while it is strictly less than the size of the array.
Pointer arithmetic not needed here for accessing the array members, and is better replaced by the index operators ([]
). More importantly, please have careful look at the types scanf
expects and the actual types of the parameters. The name
and dob
variables are already of the type char*
(or char[30]
with pointer decay), so they do not need an additional "address of" operator (&
). Viewing the compiler warnings helps in catching these kind of errors.
Here is the code with the suggested improvements:
for(i=0;i < n;i++)
{
printf("Enter name of student %d\n",(i));
scanf("%s",st[i].name);
printf("Enter Roll No of student %d\n",(i));
scanf("%d",&st[i].rollno);
printf("Enter Date Of Birth of student %d\n",(i));
scanf("%s",st[i].dob);
// ...
With this resolved, the code now skips past the switch
menu because there already is a newline character (\n
) in the input which is read by scanf
. To skip over leading whitespace (which includes newline characters), add a space character (
) before the character conversion specifier:
scanf(" %c",&ch);
Inside the switch statement, apply the same fix as earlier to the for-loop:
for(i=0; i < n;i++)
What follows are more invalid reads, probably caused by c=a; a=i; i=c;
and I am not sure what the idea behind this is.
Instead of fixing the entire program, I hope that the advice above will help you on your way to resolving the other issues yourself. It may help to write short isolated code snippets first and fully test these (e.g. by writing to certain memory and then reading from it) and afterwards incorporating these snippets into a larger program.
Also, compiling with debug info (the -g
flag) and running the program with Valgrind may help you track down where the bugs come from.
Lastly, by careful of using scanf
to read strings. Currently, it may cause buffer overflows if the input string is longer than the size of the array written to. Use, e.g., scanf("%29s",st[i].name);
to limit the maximum number of characters scanf
will read. There is more to reading input safely and predictably than I can write here, so I encourage you to look around on Stack Overflow or elsewhere yourself.
Upvotes: 1
Reputation: 1095
use getchar() instead of scanf(). This is because scanf leaves the newline you type in the input stream. Try
do
ch = getchar();
while (isspace(ch));
Upvotes: 0