I have an exercise that I need to create a program to input all information of students as a student report as the source code below. I have a problem that I can't get a full stream input. It stepped over grade input and jumped to another student to input the next student's ID. I have put getchar() to get \n but it does not help. My problem is in the case 1 of the switch, so you just need to care only about it, the other cases do not make any sense in my question.
#include <stdio.h>
#include <string.h>
#define MAX 1000
typedef struct
{
char id[10];
char name[50];
float grade;
char assess;
}student;
char assess(int a)
{
if(a<4.00)
return 'F';
if(4.00<=a<6.00)
return 'D';
if(6.00<=a<7.00)
return 'C';
if(7.00<=a<8.50)
return 'B';
if(8.50<=a<10.00)
return 'A';
}
int main()
{
int choice;
int i=0, num=0;
int a=0, j=0;
student std[MAX], temp;
char search[50];
do
{
printf("Student Report\n");
printf("1.Input data\n2.Append data\n3.Sort data and print\n4.Search by names5.Quit\n");
printf("Your choice is: ");
scanf("%d", &choice);
switch(choice)
{
case 1:
{
do{
printf("How many students you want to add?\n");
scanf("%d", &num);
if(num<0 || num>50)
printf("Your number must be positive or smaller than or equal to 50!\n");
}while(num<0||num>50);
for(i=a; i<num; i++)
{
printf("Student's id No.%d:", i);
fgets(std[i].id, 10, stdin);
getchar();
printf("Student's name No.%d:", i);
fgets(std[i].name, 50, stdin);
getchar();
printf("Student's grade No.%d:", i);
scanf("%f", &std[i].grade);
std[i].assess=assess(std[i].grade);
}
a=num;
}
case 2:
{
do
{
printf("How many students you want to append?[0; %d]\n", MAX-num);
scanf("%d", &num);
}while(num<0||num>50-a);
for(i=a; i<num+a; i++)
{
printf("Student's id No.%d:", i);
fgets(std[i].id, MAX, stdin);
getchar();
printf("Student's name No.%d:", i);
fgets(std[i].name, MAX, stdin);
getchar();
printf("Student's grade No.%d:", i);
do
{
scanf("%f", &std[i].grade);
if(std[i].grade<0||std[i].grade>10)
printf("Please re-input grade, it must be between 0 and 10\n");
}while(std[i].grade<0||std[i].grade>10);
std[i].assess=assess(std[i].grade);
}
a=num+a;
}
case 3:
{
for(i=0; i<a; i++)
for(j=0; j<a; j++)
{
if(std[i].grade<std[j].grade)
{
temp=std[i];
std[i]=std[j];
std[j]=temp;
}
}
printf("ID\tName\t\t\tGrade\t\tAssessment\n");
for(i=0; i<a; i++)
printf("%-10s%-50s%-10.2f%-10c\n", std[i].id, std[i].name, std[i].grade, std[i].assess);
}
case 4:
{
printf("Student's name who you want to search: ");
fgets(search, MAX, stdin);
getchar();
for(i=0; i<a; i++)
if(strcasecmp(search, std[i].name)==0)
printf("%-10s%-50s%-10.2f%-10c\n", std[i].id, std[i].name, std[i].grade, std[i].assess);
}
case 5:
break;
default:
{
printf("Please reinsert your choice again\n");
break;
}
}
}while(choice!=5);
return 0;
}
The issue stems from \n not being consumed by scanf at first. To overcome the case I have added while ((c = getchar()) != '\n' && c != EOF);.
To get rid of \n character after fgets's usages, I'd prefer to use strcspn.
case 1:
{
do{
printf("How many students you want to add?\n");
scanf("%d", &num);
int c;
while ((c = getchar()) != '\n' && c != EOF);
if(num<0 || num>50)
printf("Your number must be positive or smaller than or equal to 50!\n");
}while(num<0||num>50);
for(i=a; i<num; i++)
{
printf("Student's id No.%d:", i);
fgets(std[i].id, 10, stdin);
std[i].id[strcspn(std[i].id, "\n")] = 0;
printf("Student's name No.%d:", i);
fgets(std[i].name, 50, stdin);
std[i].name[strcspn(std[i].name, "\n")] = 0;
printf("Student's grade No.%d:", i);
scanf("%f", &std[i].grade);
std[i].assess=assess(std[i].grade);
}
a=num;
break;
}
Moreover, asses function can be simplified as the following.
char assess(double a)
{
if(a < 4.00)
return 'F';
if(a < 6.00)
return 'D';
if(a < 7.00)
return 'C';
if(a < 8.50)
return 'B';
if(a < 10.00)
return 'A';
else
return -1; // the error indicator to be handled.
}
Further, after each case, you should put break statements. Glance at switch usage.
Based on the recommendation I found here - I am not able to flush stdin
We can use the below snippet to get rid of the junk in the buffer.
int c;
while ((c = getchar()) != '\n' && c != EOF);
Now the question is - where to put it in your program?
Well, I put it in the for loop and got the program to run and read all the three params - viz. ID, name, grade; for several entries of students.
Please check the below modified snippet from your program.
for(i=a; i<num; i++)
{
int c; // line 1 added
while ((c = getchar()) != '\n' && c != EOF); // line 2 added
printf("Student's id No.%d:", i);
fgets(std[i].id, 10, stdin);
printf("Student's name No.%d:", i);
fgets(std[i].name, 50, stdin);
printf("Student's grade No.%d:", i);
scanf("%f", &std[i].grade);
std[i].assess=assess(std[i].grade);
}
Related
After running the next code, in the function get_data(), everything runs normally until I get to the end of the For, when program should call the function continue_function() but in somehow, ignores it, and the program just ends.
Am I calling it in a wrong way?
I'm just start learning programming in C and this is one of the last exam's exercises.
#include <stdio.h>
#define MAX 100
#define YES 1
#define NO 0
struct record
{
char fname[15+1];
char lname[20+1];
char phone[9+1];
long income;
int month;
int day;
int year;
};
struct record list[MAX];
int last_entry = 0;
void get_data(void);
void display_report(void);
int continue_function(void);
void clear_kb(void);
main()
{
int cont = YES;
int ch;
while(cont == YES)
{
printf("\n");
printf("\n MENU");
printf("\n =========\n");
printf("\n1. Enter Names");
printf("\n2. Print Report");
printf("\n3. Quit");
printf("\n\nEnter Selection ==> ");
scanf("%d", &ch);
clear_kb();
system("cls");
switch(ch)
{
case 1: get_data();
break;
case 2: display_report();
break;
case 3: printf("\n\nThank You for using this Program!");
cont = NO;
break;
default: printf("\n\nInvalid Choice, Please Select 1 to 3!");
break;
}
}
}
void get_data(void)
{
int cont;
int ctr;
for(cont = YES; last_entry < MAX && cont == YES; last_entry++)
{
printf("\n\nEnter information for Person %d.", last_entry+1);
printf("\n\nEnter first name: ");
gets(list[last_entry].fname);
printf("Enter last name: ");
gets(list[last_entry].lname);
printf("Enter phone in 123-4567 format: ");
gets(list[last_entry].phone);
printf("Enter Yearly Income: ");
scanf("%ld", &list[last_entry].income);
printf("Enter Birthday: ");
do
{
printf("\n\tMonth (0 - 12): ");
scanf("%d", &list[last_entry].month);
}
while (list[last_entry].month < 0 || list[last_entry].month > 12);
do
{
printf("\tDay (0 - 31): ");
scanf("%d", &list[last_entry].day);
}
while (list[last_entry].day < 0 || list[last_entry].day > 31);
do
{
printf("\tYear (1800 - 2025): ");
scanf("%d", list[last_entry].year);
}
while (list[last_entry].year < 1800 || list[last_entry].year > 2025);
cont = continue_function();
}
if(last_entry == MAX)
{
printf("\n\nMaximum Number of Names has been entered!\n");
}
}
void display_report(void)
{
long month_total = 0, grand_total = 0;
int x, y;
fprintf(stdout, "\n\n");
fprintf(stdout, "\n REPORT");
fprintf(stdout, "\n ========");
for(x = 0; x <= 12; x++)
{
month_total = 0;
for(y = 0; y < last_entry; y++)
{
if(list[y].month == x)
{
fprintf(stdout, "\n\t%s %s %s %ld", list[y].fname, list[y].lname, list[y].phone, list[y].income);
month_total += list[y].income;
}
}
fprintf(stdout, "\nTotal for month %d is %ld:", x, month_total);
grand_total += month_total;
}
fprintf(stdout, "\n\nReport Totals:");
fprintf(stdout, "\nTotal Income is %ld", grand_total);
fprintf(stdout, "\nAverage Income is %ld", grand_total/last_entry);
fprintf(stdout, "\n\n* * * End of Report * * *");
}
int continue_function(void)
{
char ch;
printf("\n\nDo you wish to continue? (Y)es/(N)o: ");
getc(ch);
while(ch != 'n' && ch != 'N' && ch != 'y' && ch != 'Y')
{
printf("\n%c is invalid!", ch);
printf("\n\nPlease enter \'N\' to Quit or \'Y\' to Continue: ");
getc(ch);
}
clear_kb();
if(ch == 'n' || ch == 'N')
{
system("cls");
return(NO);
}
else
{
system("cls");
return(YES);
}
}
void clear_kb(void)
{
char junk[80];
gets(junk);
}
You're not using your get functions properly:
https://www.tutorialspoint.com/c_standard_library/c_function_getc.htm
int getc(FILE *); for instance requires a FILE* as argument and returns the character, but you are passing the character as argument, it should look like ch = getc(stdin);.
On another note, notice that when you use scanf you pass &c? This is because for a value to be modified, you need to pass the address where it's stored (&) and not the value itself. So even if getc took a char, it would have to be getc(&ch).
You should follow a quick tutorial on pointers and types, if you come from a higher level language or if you're new that could be a good idea.
Just as the title said, I tried to make a function that finds max/min grades from a list of grade structs by creating a new variables that stores highest/lowest grades and then compare it with each instance in an array of struct to find the desired result. However, my function does not work as intended and it returns both max grade for both function min and max
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
struct student{
char name[50], studentID[50];
float grade;
} std[30];
int n;
void add(){
for (int i=0; i<n; i++){
printf("\nAdd the students details no%d", i+1);
printf("\n**********************************");
printf("\nStudent's name: ");
scanf(" %s", &std[i].name);
getchar();
printf("\nStudent's ID: ");
scanf(" %s", &std[i].studentID);
getchar();
printf("\nStudent's grade: ");
scanf(" %f", &std[i].grade);
getchar();
system("cls");
}
}
void displayRecords(){
for (int i=0; i<n; ++i){
printf("\n**************************");
printf("\nStudent's name: %s", std[i].name);
printf("\nStudent's ID: %s", std[i].studentID);
printf("\nStudent's grade: %.2f", std[i].grade);
printf("\n**************************\n");
}
getch();
}
float max(){
float maxGrade = std[0].grade;
for (int i=0; i<n; i++){
if(std[i].grade > maxGrade);
maxGrade = std[i].grade;
}
printf("Max grade: %.2f", maxGrade);
getch();
return maxGrade;
}
float min(){
float minGrade = std[0].grade;
for (int i=0; i<n; i++){
if(std[i].grade < minGrade);
minGrade = std[i].grade;
}
printf("Min grade: %.2f", minGrade);
getch();
return minGrade;
}
int main() {
while(1){
int a;
system("cls");
printf("\t\t\t\t----------Welcome to SMS----------");
printf("\n\t\t\t\t\tPlease choose your action");
printf("\n\t\t\t\t1.Create new record");
printf("\n\t\t\t\t2.View a record");
printf("\n\t\t\t\t3.Find max grade");
printf("\n\t\t\t\t4.Find min grade");
printf("\n\t\t\t\t5.Exit");
printf("\n\n\n\t\t\t\tYour choice: ");
scanf("%d", &a);
switch(a){
case 1:
system("cls");
printf("Please enter the amount of records you want to add <1-30>: ");
scanf("%d", &n);
add(n);
break;
case 2:
system("cls");
displayRecords(n);
break;
case 3:
system("cls");
max(n);
break;
case 4:
system("cls");
min(n);
break;
case 5:
system("cls");
printf("\n\t\t\t\t\t\tSee you again next time!");
getch();
return 0;
default:
system("cls");
printf("Error! Please enter again");
}
}
}
OP's if() ends too early for min and max.
// Bad
if(std[i].grade < minGrade);
minGrade = std[i].grade;
// Should be
if(std[i].grade < minGrade)
minGrade = std[i].grade;
Look carefully.
Best to enable all compiler warnings to save you and us time.
So, I managed to wrangle some code to get part of my program working. My program has to have a prompt to enter grades (done), repeat in a loop until broken (doneish), and print results of each grade entered. The last part is where I am stuck. I can't seem to find a good way to get any grade I entered to print at the end. I just want a "you entered ###, ###, ###," or something similar, but it can be up to 100 numbers. Below is what I have so far
#include <stdio.h>
#define MAX_ARRAY_SIZE 100
int main(void) {
int grade[MAX_ARRAY_SIZE];
int entryCount = 0;
char continueResponse;
printf("Enter an grade of between 1 and 100. \n");
printf("Enter a maximum of %d grades. \n", MAX_ARRAY_SIZE);
int i;
for(i = 0; i < MAX_ARRAY_SIZE; i++) {
printf("Enter grade: ");
scanf("%d", &grade[i]);
printf("Continue? (y/n): ");
scanf(" %c", &continueResponse);
entryCount++;
if(continueResponse == 'n' || continueResponse == 'N') {
printf(" == End of Data Entry ==\n\n");
break;
}
}
return 0;
}
Keep in mind this is third week of doing this, so I know next to nothing. If there's a "why did you do this like this", the answer is because that's how I've done it before and it works. I appreciate any input!
After your dataentry loop:
for(i = 0; i < MAX_ARRAY_SIZE; i++) {
...
}
You just have to add a second loop:
for(i = 0; i < entryCount; i++) {
printf ("%d ", grade[i]);
}
You've recorded entryCount entries to the array, numbered 0 ... entryCount - 1; you'd use another for loop to print them. For nicer formatting we do not print ", " after the last number:
printf("You've entered ");
for (i = 0; i < entryCount; i++) {
if (i == entryCount - 1) {
printf("%d", grade[i]);
}
else {
printf("%d, ", grade[i]);
}
}
printf("\n");
what I understood about your problem the following code would work:
#include <stdio.h>
#define MAX_ARRAY_SIZE 100
int main(void) {
int grade[MAX_ARRAY_SIZE];
int entryCount = 0;
char continueResponse;
printf("Enter an grade of between 1 and 100. \n");
printf("Enter a maximum of %d grades. \n", MAX_ARRAY_SIZE);
int i;
for(i = 0; i < MAX_ARRAY_SIZE; i++) {
printf("Enter grade: ");
scanf("%d", &grade[i]);
printf("Continue? (y/n): ");
scanf(" %c", &continueResponse);
entryCount++;
printf("you entred:\n");
for(int j=0;j<entryCount;j++)
{
printf("%d ",grade[j]);
}
if(continueResponse == 'n' || continueResponse == 'N') {
printf(" == End of Data Entry ==\n\n");
break;
}
}
return 0;
}
Can anybody help me with my code
int main(void){
int ctr,wordLength;
char theWord[99];
ctr = 0;
printf("Enter a Word: ");
scanf("%s", & );
printf("Enter the letter you want to find: ");
scanf("%s", & );
while(ctr < wordLength | theWord[ctr]=='a'){
ctr++;
}
//output
}
expecting output
Enter a Word: hello
Enter the letter you want to find: z
the letter z is not found in the word.
You can do it this way also,
#include <stdio.h>
int main(void)
{
int ctr;
char theWord[99], ch;
ctr = 0;
printf("Enter a Word: ");
scanf("%s", theWord);
printf("Enter the letter you want to find: ");
scanf(" %c", &ch );
for(int i = 0; theWord[i]; i++)
{
if(theWord[i] == ch)
ctr++;
}
if(ctr != 0)
printf("word is found\n");
else
printf("word is not found\n");
}
Yes, we can do it it using while loop also,
int i = 0;
while(theWord[i] != '\0' )
{
if(theWord[i] == ch)
ctr++;
i++;
}
if(ctr != 0)
printf("word is found\n");
else
printf("word is not found\n");
Corrected code
int main (void)
{
int ctr = 0;
int wordLength;
char theWord[99], ch;
printf("Enter a Word: ");
scanf("%s", theWord);
printf("Enter the letter you want to find: ");
scanf("%c", &ch);
while (theWord [ctr] != '\0')
{
if (theWord [ctr] == ch)
{
print("Character found at position %1", ctr);
break;
}
ctr++;
}
if (theWord [ctr] == '\0')
{
printf ("Character not found");
}
}
I did correction of your code, It works successfully with GCC
#include<stdio.h>
#include <string.h>
int main(void){
int ctr = 0,c = 0, wordLength;
char ch, theWord[99];
printf("Enter a Word: ");
scanf("%s", theWord);
printf("Enter the letter you want to find: ");
scanf("%c", & ch);
wordLength = strlen(theWord);
while(theWord[ctr] != '\0')
{
if (theWord[ctr] == ch)
{
printf("the letter %c is found in the word\n", ch);
c++;
}
ctr++;
}
if (c == 0 )
{
printf("the letter %c is NOT found in the word\n", ch);
}
}
This is a homework problem. I have a C program that takes user input for a number of people's first names, last names, and ages. Right now it works and prints out the names to the console correctly, but it is not printing out the right ages, and I can't figure out what I'm doing wrong. Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int choice;
int i = 0;
int x,k,l;
fputs("How many people would you like to add? ", stdout);
scanf(" %d", &choice);
fflush(stdout);
int ch;
while((ch = getchar()) != EOF && ch != '\n');
if (ch == EOF)
{
}
char firstName[choice][20];
char lastName[choice][20];
int age[choice][3];
char first[20];
char last[20];
int a[3];
for (x = 0; x < choice; x++)
{
for (l = 0; l < 3; l++)
{
age[x][l] = 0;
a[l] = 0;
}
}
while(i < choice)
{
printf("Enter the first name of person ");
printf(" %d", i);
printf(": ");
fgets(first, 20, stdin);
for (k = 0; k < 20; k++)
{
firstName[i][k] = first[k];
}
i++;
}
i = 0;
while(i < choice)
{
printf("Enter the last name of person ");
printf(" %d", i);
printf(": ");
fgets(last, 20, stdin);
for (k = 0; k < 20; k++)
{
lastName[i][k] = last[k];
}
i++;
}
i = 0;
while(i < choice)
{
fputs("Enter the age of person ", stdout);
printf(" %d", i);
printf(": ");
scanf(" %d", &a);
fflush(stdout);
for (l = 0; l < 3; l++)
{
age[i][l] = a[l];
}
i++;
}
int sh;
while((sh = getchar()) != EOF && sh != '\n');
if (sh == EOF)
{
}
for (x = 0; x < choice; x++)
{
printf("First name ");
printf(": ");
printf("%s ", firstName[x]);
printf("\n");
printf("Last name ");
printf(": ");
printf("%s ", lastName[x]);
printf("\n");
printf("Age ");
printf(": ");
printf("%d ", &age[x]);
printf("\n");
}
return 0;
}
If you copy/paste this code it will run, but the age outputted will be incorrect. Can anyone tell me why this is? Thank you!
scanf(" %d", &a);
That should be:
scanf(" %d", &a[0]);
And the printf should be printf("%d", age[x][0]);
You want to read into the first element of the array, not the entire array. You want to print out the first element of the array, not the address of the array.
A better solution would probably be not to make age an array of 3 at all. Each person only has one age. The changes would be:
int age[choice];
int a;
scanf(" %d", &a);
age[choice] = a;
printf("%d ", age[x]);