The compiler does not show any error but the second and the third gets() functions do not seem to work as expected. Instead the next line of code gets executed.
#include <stdio.h>
#include <string.h>
struct student {
char name[100], result[100];
int marks;
} s1, s2, s3;
main() {
printf("Enter the name of the student s1:");
gets(s1.name);
printf("Enter the marks obtained by the student s1:");
scanf("%d", &s1.marks);
printf("Enter the name of the student s2:");
gets(s2.name);
printf("Enter the marks obtained by the student s2: ");
scanf("%d", &s2.marks);
printf("Enter the name of the student s3:");
gets(s3.name);
printf("Enter the marks of the student s3:");
scanf("%d", &s3.marks);
if ((s1.marks > s2.marks) & (s1.marks > s3.marks))
printf("the student s1 has got the highest marks");
else
if ((s2.marks > s3.marks))
printf("The student s2 has got the highest marks");
else
printf("The student s3 has got the highest marks");
}
This is because you are mixing up gets (which is deprecated*) and scanf.
End-of-line mark from scanf remains in the buffer, so when gets tries to read the next input, it treats it as an empty line.
You can fix this by using scanf for all your input, including strings:
printf("Enter the name of the student s1:");
scanf("%99s", s1.name); // Use "%99[^\n]" to allow multi-part names
printf("Enter the marks obtained by the student s1:");
scanf("%d", &s1.marks);
* gets is deprecated, so you should use fgets(s1.name, sizeof(s1.name), stdin) instead. Here is a reference for fgets.
Use scanf("%d ",&s1.marks);. The space after %d would escape the \n that you enter after the number. If we do not do that, gets() will read "\n" as the next string input.
This should work:
#include <stdio.h>
struct student {
char name[100], result[100];
int marks;
} s1,s2,s3;
int main() {
printf("Enter the name of the student s1:");
scanf("%s", s1.name);
printf("Enter the marks obtained by the student s1:");
scanf("%d", &s1.marks);
printf("Enter the name of the student s2:");
scanf("%s", s2.name);
printf("Enter the marks obtained by the student s2: ");
scanf("%d", &s2.marks);
printf("Enter the name of the student s3:");
scanf("%s", s3.name);
printf("Enter the marks of the student s3:");
scanf("%d", &s3.marks);
if ((s1.marks > s2.marks) && (s1.marks > s3.marks))
printf("the student s1 has got the highest marks");
else if((s2.marks > s3.marks))
printf("The student s2 has got the highest marks");
else
printf("The student s3 has got the highest marks");
return 0;
}
Related
I'm new to C, and currently trying to practice on some simple codes, and I'm currently stuck with that next one.
After entering the first customer data, and repeat the code... View_customer function fails to show the saved data, and when I try to go to enter a second account data, it fails at the second entry.
#include<stdio.h>
#include<stdlib.h>
typedef struct cust{
char name[60];
int acc_no,age;
char address[60];
char citizenship[15];
double phone;
char acc_type[10];
} cust;
void new_account(int num);
void view_account(int num);
int main()
{
cust customers[10];
char answer;
int n;
int cutomer_number=1;
int cutomer_num2;
printf("Welcome To The program X: \n");
do{
printf("\n How can we serve you today? \n 1.Create a new account \n 2.Print an existing Account info \n ");
scanf("%d",&n);
if (n==1)
{
new_account(cutomer_number);
cutomer_number++;
}else {
printf("Please enter your Cust number: ");
scanf(" %d",&cutomer_num2);
view_account(cutomer_num2);
};
printf("\n Press Y to continue. Press any Key To Exit: ");
scanf(" %c",&answer);
}while (answer == 'Y' || answer == 'y');
return 0;
}
void view_account(int n)
{
cust customers[n];
printf("Your name is %s \n ", customers[n].name);
printf("Your age is %d \n", customers[n].age);
printf("Your address is %s \n", customers[n].address);
printf("Your citizenship is %s \n", customers[n].citizenship);
printf("Your phone number is %f \n", customers[n].phone);
printf("Your account type is %s \n", customers[n].acc_type);
};
void new_account(int n)
{
cust customers[n];
customers[n].acc_no = n;
printf("You are the customer number %d \n", customers[n].acc_no);
printf("Please, Enter your name: ");
scanf("%s", &customers[n].name);
printf("Please, Enter your age:");
scanf(" %d", &customers[n].age);
printf("Please, Enter your address: ");
scanf(" %s", &customers[n].address);
printf("Please, Enter your citizenship: ");
scanf(" %s", &customers[n].citizenship);
printf("Please, Enter your phone number: ");
scanf(" %f", &customers[n].phone);
printf("Please, Enter your account type: ");
scanf(" %s", &customers[n].acc_type);
}
>
Each of your three functions declares its own customers array variable, so each of them has their own memory for the customer data. Moreover, the array of new_account goes out of scope at the end of the function, so you can no longer safely access the data. Because of how C compilers typically work, the customer data is not immediately erased from memory, so your view_account function might still be able to read it, but that is what is called "undefined behavior". Which means it might work, or it might not.
Try to pass down the array from the main function to the other two functions in parameters. Or, to make things simpler at first, you could also turn the local customers variable of main into a global variable.
cust customers[10];
int main(int argc, char *argv[])
{
char answer;
int n;
int cutomer_number=1;
int cutomer_num2;
printf("Welcome To The program X: \n");
...
}
void view_account(int n) {
printf("Your name is %s \n ", customers[n].name);
...
}
void new_acccount(int n)
{
customers[n].acc_no = n;
...
}
Note that there are further issues in your code, like not checking the return value of scanf or overflowing the char arrays of the struct if you enter too many characters (missing bounds and length checking), or being able to enter more than 10 customers and accessing out of bounds of the customers array, or not using customers[0] (because your customer_number starts at 1, but array indices are 0-based). But I will not go into further details here to keep the answer focused.
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 2 years ago.
MY CODE:
#include<stdio.h>
char main()
{
char g1,g2,g3;
printf("Enter the grade of student 1: ");
scanf("%c",&g1);
printf("\nEnter the grade of student 2: ");
scanf("%c",&g2);
printf("\nEnter the grade of student 3: ");
scanf("%c",&g3);
printf("%c%c%c",g1,g2,g3);
return 0;
}
OUTPUT:
Enter the grade of student 1: A
Enter the grade of student 2:
Enter the grade of student 3:
//I am getting a line break and couldn't enter the value of student 2 and the cursor moves to student 3!!
Try doing:
#include<stdio.h>
char main()
{
char g1,g2,g3;
printf("Enter the grade of student 1: ");
scanf(" %c",&g1);
printf("\nEnter the grade of student 2: ");
scanf(" %c",&g2);
printf("\nEnter the grade of student 3: ");
scanf(" %c",&g3);
printf("%c%c%c",g1,g2,g3);
return 0;
}
Sorry, I'm new to this.
Just give a space before %c in scanf to get desired input. The below is your own code where I've added space in the second and third scanf statements.
#include<stdio.h>
char main()
{
char g1,g2,g3;
printf("Enter the grade of student 1: ");
scanf("%c",&g1);
printf("\nEnter the grade of student 2: ");
scanf(" %c",&g2);
printf("\nEnter the grade of student 3: ");
scanf(" %c",&g3);
printf("%c%c%c",g1,g2,g3);
return 0;
}
And well, the reason? If you don't, then the next scanf statement assumes the new line you create by pressing "Enter" as a new character, which is \n. So we add a space in scanf to let the statement know that space is not considered an input.
It is often easier to always read an entire line, like this:
#include <stdio.h>
void ReadLine(char result[], int resultLen)
{
int ch, i;
i = 0;
ch = getchar();
while ((ch != '\n') && (ch != EOF)) {
if (i < resultLen - 1) {
result[i] = ch;
i++;
}
ch = getchar();
}
result[i] = '\0';
}
int main(void)
{
char g1[2], g2[2] ,g3[2];
printf("Enter the grade of student 1: ");
ReadLine(g1, sizeof g1);
printf("Enter the grade of student 2: ");
ReadLine(g2, sizeof g2);
printf("Enter the grade of student 3: ");
ReadLine(g3, sizeof g3);
printf("%s%s%s\n", g1, g2, g3);
return 0;
}
first Scanf will not read/flush the "\n" after reading the single char.
this character on input buffer will make the 2nd and 3rd scanf to get execute and fail without actually prompting the user.
There are multiple ways to handle this.
read complete line
use gets/fgets to rad complete inputline
then use scanf to read from buffer
eg:
fgets(buff, 255, stdin);
sscanf(buff, "%c", &value);
execute a char read after every scanf statement.
getch()
Put a preceeding " " in front of every "%c" used in scanf.
this will skip the special char.
"scanf(" %c", &value);"
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 4 years ago.
I wrote this C program to enter names and ages of 3 people. But the output wasn't my expectation. It was able to enter name and age for the first person, but it wasn't able for second and third persons. Please help.
#include <stdio.h>
#include <string.h>
int main()
{
int i, age;
char name[20];
for(i=0; i<3; i++)
{
printf("\nEnter name: ");
gets(name);
printf("Enter age: ");
scanf(" %d", &age);
puts(name);
printf(" %d", age);
}
return 0;
}
In short: Your 2nd puts is processing the '\n' from your scanf.
Fix by adding getchar(); after scanf
Explanation:
1st iteration:
printf("\nEnter name: ");
gets(name); // line is read from input
printf("Enter age: ");
scanf(" %d", &age); // a number is read from input, and the newline char ('\n') remains in buffer
puts(name);
printf(" %d", age);
2nd iteration:
printf("\nEnter name: ");
gets(name); // previously buffered newline char is read, thus "skipping" user input
printf("Enter age: ");
scanf(" %d", &age);
puts(name);
printf(" %d", age);
Same goes for 3rd iteration, and this is why you lose user input
The best way to store information of more than one person is to use struct, like
struct person {
int age;
char name[20];
};
and make array of struct, like
struct person people[3];
than use loop with accessing people[i].age and people[i].name, e.g.:
#include <stdio.h>
#include <string.h>
struct person {
int age;
char name[20];
};
#define ARR_SIZE 3
int main(int argc, char* argv[])
{
struct person people[ARR_SIZE];
int i;
char *lastpos;
for(i = 0; i < ARR_SIZE; i++)
{
printf("\nEnter name: ");
scanf(" %s", people[i].name);
if ((lastpos=strchr(people[i].name, '\n')) != NULL) *lastpos = '\0'; // remove newline from the end
printf("Enter age: ");
scanf(" %d", &people[i].age);
}
printf("This is the people you entered:\n");
for(i = 0; i < ARR_SIZE; i++)
{
printf("%d : %s : %d\n", i+1, people[i].name, people[i].age);
}
return 0;
}
UPDATE:
As you see I use scanf(" %s", people[i].name); instead of gets(people[i].name); to read name from stdin. Try both option for the following cases:
enter short name (e.g. John) and correct age (e.g. 15)
enter two word name (e.g. John Smith) and correct age (e.g. 17)
enter short name and uncorrect age (e.g. five)
Then read articles about value returned by scanf and cleaning input buffer
I just ended up writing these codes. It is a structure of data which is supposed to be written in the FILE. I want all the strings to be entered by the user with spaces in between.
I used fgets(), but fgets() produces a newline in the time of reading the file. Any way to do it? And please explain if any buffer overflow occurs. Thank you.
#include <stdio.h>
FILE *student_records;
struct studentdetails{
char name[20];
int age;
int class_room;
char section[10];
char fathername[20];
char mothername[20];
}totalstudentdetails;
struct studentmarks{
int physics;
int chemistry;
int maths;
int biology;
int english;
}totalstudentmarks;
int main()
{
student_records=fopen("studentrec.dat","a+");
printf("\n ADD STUDENT RECORDS \n\n\n");
printf(" Enter Student Name > ");
scanf("%s",totalstudentdetails.name);
printf(" Enter Student Age > ");
scanf("%d", &totalstudentdetails.age);
getchar();
printf(" Enter Student Class > ");
scanf("%d", &totalstudentdetails.class_room);
getchar();
printf(" Enter Student Section > ");
scanf("%s", totalstudentdetails.section);
printf("Enter Student Father's Name > ");
scanf("%s",totalstudentdetails.fathername);
getchar();
printf("Enter Student mother's Name > ");
scanf("%s",totalstudentdetails.mothername);
getchar();
fwrite(&totalstudentdetails, sizeof(totalstudentdetails), 1, student_records);
/* Student marks details */
printf("\n\n\n\n");
printf(" Marks Obtained(Out Of 100) \n\n");
printf(" Enter Mark In Physics > ");
scanf("%d", &totalstudentmarks.physics);
getchar();
printf(" Enter Mark In Chemistry > ");
scanf("%d", &totalstudentmarks.chemistry);
getchar();
printf(" Enter Mark In Maths > ");
scanf("%d", &totalstudentmarks.maths);
getchar();
printf(" Enter Mark In Biology > ");
scanf("%d", &totalstudentmarks.biology);
getchar();
printf(" Enter Mark In English > ");
scanf("%d", &totalstudentmarks.english);
getchar();
fwrite(&totalstudentmarks, sizeof(totalstudentmarks), 1, student_records);
/* closing file */
fclose(student_records);
}
This is a program for a class project. It is suppose to be able to create and edit structures. The CreatRec function works fine. For the ModifyRec I am trying to send it the array by pointers in order to avoid having to "copy" the data. However, I am having trouble getting it to actually change the array. ATM The line at the bottom (gr[change].lastname= *info;) is not working at all. I really have no clue what I am doing wrong here.
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
struct student{
int recordname;
char lastname[10];
char firstname[10];
float math;
float english;
float science;
};
//prototypes
int menu();
struct student CreatRec(int);
void ModifyRec(struct student*);
void main()
{
int option, j;//option will be for users menu choice, j makes for loop work for creatrec
struct student grades[10];
j = 0;
option=Menu();
if (option == 1)
for (j = 0; j<10; j++)
(grades[j + 0]) = CreatRec(j);
else if (option==2)
ModifyRec(grades);//dont need & is smart bc array
printf("%s",grades[0].lastname);//This line is checking to see if ModifyRec actaully worked
//free(grades);2
while (1);
}
int Menu()
{
int choi;
printf("Please choose one of the following options.\n 1) Create New Student Records.\n 2) Modify an Existing Student Record\n");
printf(" 3) Print a New Sutdent Record.\n 4) Quit\n");
scanf("%d", &choi);
return choi;
}
struct student CreatRec(int i)
{
struct student qr;
//qr = (struct student*)malloc(sizeof(struct student)*6);
printf("RecordNum %i\n", i);
printf("Please enter last name-->");
scanf("%s", &qr.lastname);
printf("Please enter first name-->");
scanf("%s", &qr.firstname);
printf("Please math grade-->");
scanf("%f", &qr.math);
printf("Please english grade-->");
scanf("%f", &qr.english);
printf("Please science grade-->");
scanf("%f", &qr.science);
return qr;
}
void ModifyRec(struct student gr[])
{
int change;
char feild[10], info[10];
printf("Which record would you like to change?\n");
scanf("%d", &change);
rewind(stdin);
printf("Which feild would you like to edit?\n");
scanf("%s", &feild);
rewind(stdin);
printf("Enter info\n");
scanf("%s", &info);
if (!strcmp("lastname", feild))
gr[change].lastname= *info;//NOT WORKING
}
First of all I do not see a great sense in expression grades[j + 0] of statement
for (j = 0; j<10; j++)
(grades[j + 0]) = CreatRec(j);
These statements
printf("Please enter last name-->");
scanf("%s", &qr.lastname);
printf("Please enter first name-->");
scanf("%s", &qr.firstname);
have to be substituted for
printf("Please enter last name-->");
scanf("%s", qr.lastname);
printf("Please enter first name-->");
scanf("%s", qr.firstname);
And this statement
if (!strcmp("lastname", feild))
gr[change].lastname= *info;//
has to be substituted for
if (!strcmp("lastname", feild))
strcpy( gr[change].lastname, info );
gr[change].lastname is a char array, not a pointer. You can't reassign it. In this case, you probably ought to do scanf("%s", gr[change].lastname); and skip char info[10] altogether.