C scanf() doesn't parse my input - c

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);

Related

How do i fix this error? Switch statement

#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));

Not an Expected Result Loop of a Structure in c [closed]

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;
}

Logical issue with printf and scanf

I am revising my basic C to prepare for the upcoming quiz, when i was writing a function to simply take a character input and store it into a struct and print it out again. There is no issue with the compiling whatsoever but i kept getting logical issue. How do i fix this?
#include <stdio.h>
struct player
{
char letter;
int age;
double avg;
};
int main()
{
struct player P1;
char name;
int age;
double avg;
printf("Enter age: ");
scanf("%d", &age);
printf("Enter avg: ");
scanf("%lf", &avg);
printf("Enter name: ");
scanf("%s", &name);
P1.letter= name;
P1.avg = avg;
P1.age = age;
printf("\n Age is: %d \n", P1.age);
printf("Avg is: %lf", P1.avg);
printf(" \n Name is: %c \n", P1.letter);
return 0;
}
If i put in '1' for int, output would be "Age is: 0'
you are trying to get name, age and avg. of the player. so to store name , you should declare an array not a character. and for assigning the name to structure variable use strcpy().(direct assignment not works). OR if you taking only a single character as a name then write scanf like this:
scanf("%c", &name);
check below code, it will help you,
#include <stdio.h>
struct player
{
char letter[10];
int age;
double avg;
};
int main()
{
struct player P1;
char name[10];
int age;
double avg;
printf("Enter age: ");
scanf("%d", &age);
printf("Enter avg: ");
scanf("%lf", &avg);
printf("Enter name: ");
scanf("%s", &name);
strcpy(P1.letter,name);
P1.avg = avg;
P1.age = age;
printf("\n Age is: %d \n", P1.age);
printf("Avg is: %lf", P1.avg);
printf(" \n Name is: %s \n", P1.letter);
return 0;
}
You are using a character data type for entering a string, "char name" which is leading you to undefined behavior.
Instead of that you declare a character array like this "char name[10]" and then read name. but while assigning you have to take care that you can not assign directly you have to use strcpy like this.
strcpy(p1.letter,name) (Here letter is also character array)
Two quick suggestions:
1) Unless you are certain the name buffer will be populated only by short names, (9 or less characters), pick a more reasonable size for the buffer, such as:
char name[100];
This will also require lengthening the member letter in your struct.
2) when using scanf() to read in variables, the address of the variable being read is passed as the 2nd argument. For variables such as int a; or float b; you must use the address of operator: & as a prefix to the variable. But because the variable name of a C string points to the first character in the array, it already is the address of that variable. So you do not need the explicit & operator when reading a C string into the scanf() function. The return value of the function should also be used to determine if the call was successful. Change the following line as shown:
scanf("%s", &name);
int count = scanf("%s", name);//note: use return value of function
// remove & ^
if(count < 0)
{
//handle error
}

invalid character are printed in program

I have written the program
#include<stdio.h>
struct student
{
char name[22];
char rollno[10];
unsigned long long int phno;
};
int main()
{
int i,j;
char c[1];
struct student cse[10],*p;
p=cse;
for(i=0;i<3;i++)
{
printf("enter student name\n");
gets(cse[i].name);
printf("enter student roll number \n");
gets(cse[i].rollno);
printf("enter student phone number \n");
scanf("%llu",&cse[i].phno);
gets(c); //to catch the '\n' left unprocessed by scanf
}
for(i=0;i<3;i++);
printf("the following is the information about CSE B student\n");
printf("%-6s%-24s%-14s%-14s \n","S.no","student Name","Roll no","phone no.");
for(i=0;i<3;i++)
{
printf("%-6d%-24s%-20s%-14llu \n",i+1,(*p).name,(*p).rollno,(*p).phno);
++p;
}
return 0;
}
the output is
the following is the information about CSE B student
S.no student Name Roll no phone no.
1 kapil 1234567890��I 1234567890
2 kumar 9876543210��L 9876543210
3 sharma 5123467890��a1 5123467980
there are some unwanted and ununderstandable characters in the Roll no coloumns ,what is the cause of printing of those invalid characters
~
The array rollno has storage only for 10 chars but you are inputting 10 or more chars. If your roll numbers are 10 digits, you need at least 11 chars to print it as string, one extra for the terminating null-byte. This is technically undefined behaviour, making your program invalid.
Note that gets() has been deprecated since C11 and you should really be using fgets() instead.

while loop asks user input one time only

#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.

Resources