Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I am working on a simple C program which is to create a loop of a structure.
So I have a structure of a Students with name, age, and grade.
So the output will be something like this:
Enter name of student 1:
Enter age of student 1:
Enter Grade of student 1:
Enter name of student 2:
Enter age of student 2:
Enter Grade of student 2:
But after I input the grade of Student 1, it skipped The name of student 2 so I got this instead:
Enter name of student 1:
Enter age of student 1:
Enter Grade of student 1:
Enter name of student 2: Enter age of student 2:
And I am using DevC++, here is my code:
#include <stdio.h>
struct student {
char name[50]; // declare name using array
int age;
int grade;
};
int main ()
{
struct student info[3]; //declare 3 students [3]
int i;
for(i=1;i<=3;i++) { // this is for the looping, student 1, student 2, student 3
printf("Enter name for student %d : ",i);
scanf("%s",info[i].name); // called struct using "." (dot)
printf("Enter age for sudent %d : ",i);
scanf("%d",&info[i].age);
printf("Enter grade for student %d : ",i);
scanf("%d",&info[i].grade);
}
return 0;
}
Can someone find what is wrong with my code? or please help a suggestion to solve this problem to get the expected result.
Multiple suggestions of your code:
When using scanf to input data, always check its return value to make sure sufficient data is input correctly, for example, when you input B for the int grade field, it returns zero instead of one:
int r = scanf("%d", &info[i].grade);
printf("%d\n", r); // 0
Also as said in the comments, when you input strings try use fgets, because it is more secure and will not stop at spaces. scanf does not check for buffer overflow.
Also, in your for loop, you are accessing out of bounds of the array info, you have to start from 0.
Try the following:
int main ()
{
struct student info[3]; //declare 3 students [3]
int i;
int r;
for(i=0; i < 3; i++) {
printf("Enter name for student %d : ",i);
fgets(info[i].name, 50, stdin);
printf("Enter age for sudent %d : ",i);
r = scanf("%d", &info[i].age);
if (r < 1) {
printf("input error, exiting\n");
return 1;
}
printf("Enter grade for student %d : ",i);
r = scanf("%d", &info[i].grade);
if (r < 1) {
printf("input error, retry\n");
return 1;
}
}
return 0;
}
I Tried your code and it work succesfully, I tried to compare it with what you have done.
And The result is you declare scanf("%d",&info[i].grade);
which is received an integer input. but when I see your picture your Input was a Character
So Just Change Your Input with an Integer on Enter grade for student i
To expand on the answer by Serafin: (Good catch, BTW!)
When you input a non-number into your scanf call,
printf("Enter grade for student %d : ",i);
scanf will fail to read the input (see comment by hyde, thanks)
scanf will skip all inputs that don't match the input pattern provided until it hits newline. Anything that was not matched read remains in the input buffer. Therefore, the subsequent call to scanf receives the old content from the previous input, which does get matched in this case.
grade is int but you type a char ('B', It's like 8 :D), I modity three line:
#include <stdio.h>
struct student {
char name[50]; // declare name using array
int age;
char grade; // int -> char
};
int main ()
{
struct student info[3]; //declare 3 students [3]
int i;
for(i=1;i<=3;i++) { // this is for the looping, student 1, student 2, student 3
printf("Enter name for student %d : ",i);
scanf("%s",info[i].name); // called struct using "." (dot)
printf("Enter age for sudent %d : ",i);
scanf("%d",&info[i].age);
getchar(); // reade '\n' after type age
printf("Enter grade for student %d : ",i);
scanf("%c",&info[i].grade); // %d -> %c
}
return 0;
}
Related
#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.
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.
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));
This question already has answers here:
What will happen if '&' is not put in a 'scanf' statement?
(6 answers)
Closed 4 years ago.
Hello I have a problem with integer. This is my code:
#include <stdio.h>
#include <stdlib.h>
struct data
{
char name[50];
int grade[1];
};
int main()
{
struct data persons[30];
int n = 3;
int i;
for(i=0;i<n;i++)
{
printf("Type person name nr: [%d] ",i+1);
scanf("%s",persons[i].name);
printf("Type grade: (from 1 to 6) ");
scanf("%d",persons[i].grade);
}
for(i=0;i<n;i++)
{
printf("Name [%d]: %s\n",i+1,persons[i].name);
printf("Grade [%d]: %d\n",i+1,persons[i].grade);
}
return 0;
}
And when I type some names and grades the output isn't correct:
This is my output
You are using an array for a single grade, when a standard int is enough.
struct data
{
char name[50];
int grade;
};
And then you also need to pass the reference of the int to scanf using an &.
scanf("%d", &persons[i].grade);
The corrected version of your program:
#include <stdio.h>
#include <stdlib.h>
struct data {
char name[50];
int grade; // In you case, to store one integer value just use int varibale because it seems more logical.
};
int main() {
struct data persons[30];
int n = 3;
int i;
for (i = 0; i < n; i++) {
printf("Type person name nr: [%d] ", i + 1);
scanf("%s", persons[i].name);
printf("Type grade: (from 1 to 6) ");
scanf("%d", &persons[i].grade); // To fill member of structure you may use '&' sign because scanf gets address.
}
for (i = 0; i < n; i++) {
printf("Name [%d]: %s\n", i + 1, persons[i].name);
printf("Grade [%d]: %d\n", i + 1, persons[i].grade);
}
return 0;
}
Also, keep in mind that compiler not always tell you that something is going to be wrong, in most cases using special flags (some of them I mentioned in the comment) for compiler can give you more information.
It's worth to note that current IDEs highlight obvious errors and really speed up your development process.
It's because grade is an array, so you need to do .grade[0]when writing or reading data to / from it, like so:
scanf("%d",persons[i].grade[0]);
...
printf("Grade [%d]: %d\n",i+1,persons[i].grade[0]);
you have to replace
printf("Grade [%d]: %d\n",i+1,persons[i].grade);
by
printf("Grade [%d]: %d\n",i+1,persons[i].grade[0]);
in the scanf you do scanf("%d",persons[i].grade); so because grade is a vector you give its address, but in the printf you have to specify the index else you print the address of the vector
However to use a vector is useless because it contains only one element, better to directly use an int for grade, and of course in that case you have to give &persons[i].grade for the scanf and persons[i].grade for
the printf
Execution :
Type person name nr: [1] a
Type grade: (from 1 to 6) 1
Type person name nr: [2] b
Type grade: (from 1 to 6) 2
Type person name nr: [3] c
Type grade: (from 1 to 6) 3
Name [1]: a
Grade [1]: 1
Name [2]: b
Grade [2]: 2
Name [3]: c
Grade [3]: 3
#include <stdio.h>
#include <stdlib.h>
struct the_struct
{
char FirstName[20];
char LastName[32];
int Score[20];
};
int main ()
{
int i,n;
struct the_struct *ptr[100];
printf("how many students?\n");
scanf("%d",&n);
while (i<=n);
{
i==0;
ptr[i] = malloc(sizeof(struct the_struct));
printf("Enter First Name \n");
scanf("%s",ptr[i]->FirstName);
printf("Enter Last Name \n");
scanf("%s",ptr[i]->LastName);
printf("Enter Score? \n");
scanf("%s",ptr[i]->Score);
printf("%s %s %s\n",ptr[i]->FirstName,ptr[i]->LastName,ptr[i]->Score);
i++;
}
}
hey guys, so when i enter the first input, it goes only once without going on for the number the user inputs, i tried the for loop but same result.
still learning C so my apology if i misunderstood something.
Thanks in advance.
Your while loop is problematic. You could rewrite it as:
for (i = 0; i < n; ++i)
{
ptr[i] = malloc(sizeof(struct the_struct));
printf("Enter First Name \n");
scanf("%s",ptr[i]->FirstName);
printf("Enter Last Name \n");
scanf("%s",ptr[i]->LastName);
printf("Enter Score? \n");
scanf("%s",ptr[i]->Score);
printf("%s %s %s\n",ptr[i]->FirstName,ptr[i]->LastName,ptr[i]->Score);
}
And since you use %s to read and print Score, you should declare it as char Score[20]; instead of int.
The problem is that i is uninitialized. Therefore, the loop while (i <= n) has undefined behavior, and can end at any time.
Add int i = 0 initializer to fix this problem.
Notes:
i == 0 expression at the beginning of the loop has no effect
Since i starts at zero, your while loop should be while (i < n), not <=.
You should check the results of scanf to see if the user entered something meaningful
You should specify the size of the array into which you read a string, e.g. scanf("%31s",ptr[i]->LastName); This prevents buffer overruns.
Whenever I insert 2 or more students, the program gives the same gpa from the first student. I insert for both every time, and how can I display the max gpa and who got it?
#include <stdio.h>
FILE *f;
struct student
{
char name[20];
int id;
int n;
float sum;
float gpa;
} s[100];
float FUN_GPA(int n);
int main ()
{
int m,i,x,b;
float max=0;
s[i].sum=0;
printf("Please Enter Number Of Students : ");
scanf("%d",&m);
for(i=0;i<m;i++)
{
printf("\nStudent %d : \n",i+1);
printf("Name : ");
scanf("%s",&s[i].name);
printf("ID : ");
scanf("%d",&s[i].id);
printf("Number Of Courses : ");
scanf("%d",&s[i].n);
}
printf("\nEnter Student Marks");
for(i=0;i<m;i++)
{
printf("\n\n\t\t\t......[ Student %d ]......\n",i+1);
for(x=0;x<s[i].n;x++)
{
printf("Course %d Mark : ",x+1);
scanf("%d",&b);
s[i].sum+=b;
}
printf("\nSum Of The Courses Marks = %3.f",s[i].sum);
printf("\nGPA For Student %d = %f",i+1,FUN_GPA(s[i].gpa));
}
if (s[i].gpa>max)
max=s[i].gpa;
printf("\n\nHighest GPA is done by Student %d with GPA = %f",i,max);
{
if((f=fopen("d:\\STUDENTS.txt","w"))==NULL)
printf("\ncant open file ");
// if((f=fopen("d:\\STUDENTS.txt","r"))==NULL)
// printf("\ncant open file ");
fprintf(f,"Name : %s\t ID : %d\t GPA = %f \n",s[i].name,s[i].id,s[i].gpa);
fclose(f);
}
}
float FUN_GPA(int i)
{
s[i].gpa=0;
s[i].gpa=s[i].sum/s[i].n;
return s[i].gpa;
}
Replace FUN_GPA(s[i].gpa) by FUN_GPA(i).
Put this inside the loop; not much use having it outside:
if (s[i].gpa>max)
max=s[i].gpa;
The same applies to this initializer, by the way:
s[i].sum=0;
In general, do not use variable i outside the loop; this is bad practice and in your particular case, totally wrong!
i is not the index of the best performing student; it is not even a correct index once the loop ends, since it refers to the array element immediately following the last registered student. Please introduce a new variable to keep track of the index of the best performer so far. Instead of i, use this new variable in the lines to follow:
fprintf(f,"Name : %s\t ID : %d\t GPA = %f \n",s[i].name,s[i].id,s[i].gpa);
Same here; do not forget to add 1 like you did everywhere else already!
printf("\n\nHighest GPA is done by Student %d with GPA = %f",i,max);
General advice: use descriptive names. i is OK afaic; s and n are not so great, m, x and b would have been good for 50 lashes from my old teachers for sure!
This needs to be in a for loop (you're only checking one as it is currently written):
if (s[i].gpa>max)
max=s[i].gpa;
You'll probably also want to keep track of which i had the max.
So something like:
int iwithmax;
for ( i = 0 ; i < m ; i++) {
if (s[i].gpa > max) {
max = s[i].gpa;
iwithmax = i;
}
}
and change print statement accordingly:
printf("\n\nHighest GPA is done by Student %d with GPA = %f",iwithmax,max);
I am writing a C program and that program objective is I want to enter only 4 students details with structures. But my program missing something so my program exiting after entering the first student details. Look at here please
# include <stdio.h>
struct student
{
int no;
char name[20];
float marks;
}s[10];
int main()
{
int i,n;
printf(" enter number of students ");
scanf("%d",&n);
printf(" enter student Number Name marks ");
for(i=0;i<n;i++)
{
scanf("%d%c%f",&s[i].no,&s[i].name,&s[i].marks);
}
return 0;
}
the program quits after entering one student details even I have selected number of students as 4 .
The inputs I am giving here as
[root#localhost raja]# gcc -o s s.c
[root#localhost raja]# ./s
enter number of students 4
enter student Number Name marks 1 as 12.03
[root#localhost raja]#
its quitting the program even after entering only 1st student details.
help me.
This is the correct code
# include <stdio.h>
struct student
{
int no;
char name[20];
float marks;
}s[10];
int main()
{
int i,n;
printf(" enter number of students ");
scanf("%d",&n);
printf(" enter student Number Name marks ");
for(i=0;i<n;i++)
{
scanf("%d%20s%f",&s[i].no,s[i].name,&s[i].marks);
}
return 0;
}
The first error is %c should be %s cause you are expecting a string and not a character.
The second is that when you are expecting %s you just need to pass in the variable name since its an array and therefore is a pointer.
20 before the s specifies the width allowed for the string for the name variable. If the length of the input string for name exceeds 20, it will mess up the input of the other variables and program will terminate or give unexpected behaviour.
This:
scanf("%d%c%f"
Should be more like this:
scanf("%d %s %f"
The wrong here :
scanf("%d%c%f",&s[i].no,&s[i].name,&s[i].marks);
The right answer is :
scanf("%d%s%f",&s[i].no,&s[i].name,&s[i].marks);