In C Scanf not grabbing inputs past the first instance of scanf - c

Coding in visual studio code
#include<stdio.h>
int main(){
char firstLetterofName;
int numOfVisits;
float priceOfDrink; //Creating the variables leaving them empty for now
float total;
printf("Hello! What is your name?\n");
scanf("%c", &firstLetterofName); //Asking for an inputting the first letter of users name
printf("How many times have you visited Starbucks in a month\n");
scanf("%d", &numOfVisits); //Asking and inputting number of visits
printf("What is the price of the drink you order?\n");
scanf("%f", &priceOfDrink); //Asking and inputting price of drink
total = priceOfDrink * numOfVisits;
printf("Wow %c! You have spent $%d on Starbuck!", firstLetterofName, total);
return 0;
}
First attempt using full name Terminal outputs
PS C:\C Cpp> cd "c:\C Cpp\" ; if ($?) { gcc test.c -o test } ; if ($?) { .\test }
Hello! What is your name?
Logan
How many times have you visited Starbucks in a month
What is the price of the drink you order?
Wow L! You have spent $0 on Starbuck!
Second attempt using only first letter
PS C:\C Cpp> cd "c:\C Cpp\" ; if ($?) { gcc test.c -o test } ; if ($?) { .\test }
Hello! What is your name?
L
How many times have you visited Starbucks in a month
5
What is the price of the drink you order?
2.0
Wow L! You have spent $0 on Starbuck!
PS C:\C Cpp>
Expected output is Wow L! You have spent $10.0 on starbucks
For the name part it is suppose to only take the first letter.

In C Scanf not grabbing inputs past the first instance of scanf
With input "Logan\n", code scans in the 'L' as the firstLetterofName with the "ogan\n" reamaining in stdin for the next input function.
scanf("%c", &firstLetterofName);
With input "ogan\n", scanf() fails and returns 0. numOfVisits was not changed. Code unfortunately did not not check the return value of scanf() to test success.
scanf("%d", &numOfVisits); // FAILED
To quickly discern scanf() troubles, check scanf() return values for success.
Do not rely on the user to enter compliant text. Robust code watches out for too much data, not enough data, non-numeric data, etc. User input is evil.
Consider using fgets() to read a line of user input and then parse the resultant string.

#include<stdio.h>
int main(){
char firstLetterofName;
int numOfVisits;
float priceOfDrink; //Creating the variables leaving them empty for now
float total;
printf("Hello! What is your name?\n");
scanf("%c", &firstLetterofName); //Asking for an inputting the first letter of users name
//clear the input stream
fflush(stdin);
printf("How many times have you visited Starbucks in a month\n");
scanf("%d", &numOfVisits); //Asking and inputting number of visits
printf("What is the price of the drink you order?\n");
scanf("%f", &priceOfDrink); //Asking and inputting price of drink
total = priceOfDrink * numOfVisits;
printf("Wow %c! You have spent $%f on Starbuck!", firstLetterofName, total);
return 0;
}
Use fflush(stdin) to flush the input stream. Availabe in gcc

Related

How to stop a C while loop at once when we keyboard input without going on to the next step?

After I run this program, it has to stop when I input -999. But it stops even after the execution of -999. What have I done wrong here?
This was the question for the code.
Input employee number, and hours worked by employees, and to display the following:
Employee number, Over Time Payment, and the percentage of employees whose Over Time Payment exceeding the Rs. 4000/-.
The user should input –999 as employee number to end the program, and the normal Over Time Rate is Rs.150 per hour and Rs. 200 per hour for hours in excess of 40.
#include<stdio.h>
int main()
{
int empno=0,tot;
float hours, otp, prcn;
while(empno!=-999){
printf("Enter the Employee No: ");
scanf("%d",&empno);
printf("Enter the No of Hours: ");
scanf("%f",&hours);
if(hours<40){
otp=hours*150.00;
}
else
otp=((hours-40)*200)+(hours*150.00);
if(otp>4000){
prcn+=1;
tot+=1;
}
else
tot+=1;
printf("\nEmployee No: %d\n",empno);
printf("Over Time Payment: %.2f\n",otp);
printf("Percentage of Employees whose OTP exceeding the Rs. 4000/-: %.2f%%\n\n",(prcn/tot)*100);
}
}
I expect it to stop when I enter -999 without going on.
There is no statement after:
printf("Enter the Employee No: ");
scanf("%d",&empno);
and before:
printf("Enter the No of Hours: ");
scanf("%f",&hours);
that would cause your program to stop after you enter -999. The while loop check happens once when you start (before you enter the first employee number) but it doesn't happen again until after you do all the data entry, calculation and printing.

How to fix infinite loop with struct in C

I have a problem with the struct when storing data. I want to make a sentinel loop so please have a look and help me thank you.
#include<stdio.h>
#include<stdlib.h>
struct Vehichle
{
char vecType[100];
char plateNo[10];
float hours;
};
struct Parking
{
int parkNo ;
// 1 =true 0=false
int availability;
};
int main()
{
int c = 0;
int x;
struct Vehichle vehicle[c];
struct Parking park[50];
int counter = 1;
while(x!=-1)
{
printf("Enter -1 to end: \n");
scanf("%d", &x);
printf("Enter Vehicle Type etc: suv,mpv and more:");
scanf("%d",&vehicle[x].vecType);
printf("Please enter parking Number :");
scanf("%d",&park[x].parkNo);
park[x].availability = 1;
counter++;
}
}
I expect that after it is stored in the struct, the program will loop.
There are a number of problems in your code. Here is your code where I have added some comments:
int main()
{
int c = 0;
int x; // UPS: x is uninitialized
struct Vehichle vehicle[c]; // UPS: c is zero so you don't get an array
struct Parking park[50];
int counter = 1;
while(x!=-1) // UPS: Use of uninitialized x
{
printf("Enter -1 to end: \n");
scanf("%d", &x);
printf("Enter Vehicle Type etc: suv,mpv and more:");
scanf("%d",&vehicle[x].vecType); // UPS: vecType is char array so
// use %s instead of %d
// and don't use a &
printf("Please enter parking Number :");
scanf("%d",&park[x].parkNo);
park[x].availability = 1;
counter++;
}
}
Besides that you have a problem when the user input is -1. The current code just continues and adds an element at index -1. That's illegal.
To fix add an extra line after the scanf. Like:
scanf("%d", &x);
if (x == -1) break; // Stop the while loop
With that change you can do while(1) instead of while(x!=-1)
Some extra comments:
You should check that the user input (aka x) is within the valid range to be used as array index.
You should also check the return value of scanf. Like:
if (scanf("%d", &x) != 1)
{
// Invalid input"
... error handling ...
}
(1) Below is an updated code as your code had several problems.
I'm sure that looking at the below code, you would be able to understand the mistakes in your code.
Feel free to use this as the base for writing your own version.
(2) Please read the inline comments carefully. The comments elaborately
explain the intention of that section of code
(3) This is just a quick code. I've not compiled/run/tested this code.
My intention is just to give you an idea about it with one possible example.
/* A very basic parking manager module
When a vehicle comes in for parking
a)capture vehicle info & parking lot number where it is parking
b)mark that lot as unavailable
When the vehicle is leaving the parking,
capture parking lot number which is being emptied,
and mark that lot as available
And, have some fun on the way.
*/
#include<stdio.h>
#define YOU_ARE_TRAPPED_BY_THE_BIG_BAD_GREEN_SCARY_MONSTER ({printf("HA HA HA, You didn't read and follow the inline comments !!\nNow stand up, jump 3 times, then sit down, and read all the comments again and do the min code modif to make me go away, else i won't let you escape the parking lot ... hoo ha ha ha ha >-)\n"); updateVehicleParkingInfo=1;})
#include<stdlib.h>
struct Vehichle{
char vecType[100]; //type of vehicle eg suv,mpv and more...
char plateNo[10]; //number plate of the vehicle
float hours; //???
};
struct Parking{
int parkNo ; //parking lot num
bool availability; //Is tbis parking space available? Yes/No
};
struct VehicleParkingInfo{
struct Vehicle vehicle; //vehicle info
struct Parking parking; //corresponding parking info
};
//maximum number of parking lots that the parking space has
#define MAX_PARKING_LOTS 10
//parking lot avaialble flags
#define PARKING_LOT_AVAILABLE true
#define PARKING_LOT_UNAVAILABLE false
//flags for vehicle coming in or leaving
#define VEHICLE_ENTERING true
#define VEHICLE_LEAVING false
void main(){
int updateVehicleParkingInfo; //flag indicating that user wants to update parking info.
int vehicleDirection; //flag for indicating whether the vehicle is coming in or going out of the parking
int parkingIdx; //index of the parking lot to fetch values from.
//array for info about all the parking lots
struct VehicleParkingInfo vehicleParkingInfo[MAX_PARKING_LOTS];
//initialize the parking & vehicle info of all the parking lots to zeros
memset(vehicleParkingInfo,0,MAX_PARKING_LOTS*sizeof(VehicleParkingInfo));
//for each parking lot, mark it as available and assign parking lot numbers serially
for(parkingIdx = 0; parkingIdx < MAX_PARKING_LOTS; parkingIdx++){
vehicleParkingInfo[parkingIdx].parking.parkNo = parkingIdx;
vehicleParkingInfo[parkingIdx].parking.availability = PARKING_LOT_AVAILABLE;
}
//get user's input if parking info needs to be updated or it is time to close and go home
printf("Update parking info? Enter 0 to end");
scanf("%d",&updateVehicleParkingInfo);
/*
**** SENTINEL LOOP ****
Continue updating the parking info until the user wants to even for unlimited number of times.
Stop only when user enters a specific value i.e. 0.
*/
while(updateVehicleParkingInfo != 0){
printf("vehicle direction? 1 for entering, 0 for leaving:");
scanf("%d",&vehicleDirection);
if(vehicleDirection == VEHICLE_ENTERING){
do{
printf("Please enter parking Number:");
scanf("%d",&parkingIdx);
//*** CRASH ALERT!!! *** Following code can crash if parkingIdx is < 0, or >= MAX_PARKING_LOTS
//TODO: (1) Add sanity check for parkingIdx (2) Add corrective steps if sanity check fails
//if parking is not available, print an error message
if(vehicleParkingInfo[parkingIdx].parking.availability == PARKING_LOT_UNAVAILABLE){
//TODO: change the below messages to fine-tune fun, humor, teasing etc levels (remember humor setting of TARS from Interstellar?)
printf("There is some other vehicle parked in this parking lot, please enter another parking lot number\n");
printf("BTW, I know which lots are available, but I won't tell you ... hehehe >-) \n, keep trying ...hoo hoo hooo\n");
}
//check if the requested parking lot is available, if yes, then take further actions, else request a new parking lot number
}while(vehicleParkingInfo[parkingIdx].parking.availability == PARKING_LOT_UNAVAILABLE);
printf("Yipee, this parking lot is available\n");
//mark this parking lot number as being used so that another vehicle cannot come here.
vehicleParkingInfo[parkingIdx].parking.availability = PARKING_LOT_UNAVAILABLE;
//get vehicle type info and
// *** CRASH ALERT!!! *** The scanf below will crash if the user enters more 99+ characters (buffer overflow)
// Best is to use fgets or getline with the stdin as the stream.
// Ref https://stackoverflow.com/questions/4023895/how-do-i-read-a-string-entered-by-the-user-in-c
// TODO: Replace below scanf() with a better/safer implmentation
printf("Enter Vehicle Type etc: suv,mpv and more:");
scanf("%s",vehicleParkingInfo[parkingIdx].vehicle.vecType);
//TODO: other steps.
}
if(vehicleDirection == VEHICLE_LEAVING){
do{
printf("Please enter parking Number:");
scanf("%d",&parkingIdx);
//*** CRASH ALERT!!! *** Following code can crash if parkingIdx is < 0, or >= MAX_PARKING_LOTS
//TODO: (1) Add sanity check for parkingIdx (2) Add corrective steps if sanity check fails
//if parking is available, print an error message
if(vehicleParkingInfo[parkingIdx].parking.availability == PARKING_LOT_AVAILABLE){
printf("It appears that the parking lot number is incorrect, please enter correct parking lot number\n");
}
//check if the requested parking lot is available, if yes, then request a new parking lot number, else proceed further
}while(vehicleParkingInfo[parkingIdx].parking.availability == PARKING_LOT_AVAILABLE);
printf("Bye bye, drive safely\n");
//mark this parking lot number as available for other incoming vehicles.
vehicleParkingInfo[parkingIdx].parking.availability = PARKING_LOT_AVAILABLE;
}
//get user's input if parking info needs to be updated or it is time to close and go home
printf("Update parking info? Enter 0 to end");
scanf("%d",&updateVehicleParkingInfo);
//TODO: remove the following line of code before running the program
YOU_ARE_TRAPPED_BY_THE_BIG_BAD_GREEN_SCARY_MONSTER;
//go back to while loop,
//check if the vehicle parking info needs to be updated,
//break if the user has entered 0
}//end of the Sentinel loop
//the above loop will run indefinitely. The user has quite a lot of ways to come out of the loop
//(1) Enter the sentinel value '0', (easiest path)
//(2) Somehow stop the program e.g. by banging his/her head really hard on the computer such that computer breaks .. etc
}//end of main()

My output is not appearing properly

I apologize if I'm not formatting my question correctly. I am new to this site and new to programming.
I'm currently working on a C assignment and I believe I have most of the code done, but there is some tuning I can't seem to figure out. I would appreciate any feedback. Here is my code
#include <stdio.h>
#include <stdlib.h>
#define SENTINAL -1
double sumOfScores = 0;
double examScore = 0;
double sumOfExams = 0;
double average = 0;
double calculateAverage();
double main(void)
{
int i;
for (i = 1; i <= 4; ++i)
{
calculateAverage();
}
return 0;
}
double calculateAverage()
{
printf("Enter %d to terminate program. \n", SENTINAL);
while(examScore != SENTINAL)
{
printf("Enter test score: \n");
scanf("%lf", &examScore);
sumOfScores += examScore;
sumOfExams++;
average = sumOfScores / sumOfExams;
}
printf("The average of the test scores entered thus far is %.2lf \n\n", average);
return 0;
}
Here is my output
Enter -1 to terminate program.
Enter test score:
99
Enter test score:
98
Enter test score:
97
Enter test score:
96
Enter test score:
-1
The average of the test scores entered thus far is 77.80
Enter -1 to terminate program.
The average of the test scores entered thus far is 77.80
Enter -1 to terminate program.
The average of the test scores entered thus far is 77.80
Enter -1 to terminate program.
The average of the test scores entered thus far is 77.80
Here is what I would like it to look like
Enter -1 to terminate program.
Enter test score:
99
Enter test score:
98
Enter test score:
97
Enter test score:
96
Enter test score:
-1
The average of the test scores entered thus far is 77.80
Enter -1 to terminate program.
Enter test score:
95
Enter test score:
94
Enter test score:
93
Enter test score:
92
Enter test score:
-1
The average of the test scores entered thus far is (avg goes here)
I did not include an additional two sets of numbers in the output I am going for, but I would like to be able to do this with four sets of numbers. As soon as I enter (-1) to terminate the first set of numbers, it automatically spits me out the average of the first set for the remaining 3 sets before i can even input the numbers I would like to enter for those. Also, why is it giving me an avg of 77.8 for the first set of values when it should be up in the 90s?
I would recommend using local variables rather than global ones. That is to say, move these lines:
double sumOfScores = 0;
double examScore = 0;
double sumOfExams = 0;
double average = 0;
Here:
double calculateAverage()
{
double sumOfScores = 0;
double examScore = 0;
double sumOfExams = 0;
double average = 0;
// ...
This will cause the variables to be reset to 0 every time the function starts rather than leaving the garbage from the last time the function ran.
I think that the reason that you are getting the wrong average is that you are including -1 as one of the test scores. You read the value, then add it to the average BEFORE you check if the value is -1.
printf("Enter test score: \n");
scanf("%lf", &examScore);
// Is examScore equal to -1 here? It might be.
// Don't add it to sumOfScores without checking!
sumOfScores += examScore;
sumOfExams++;
average = sumOfScores / sumOfExams;
You either need to test if the value is -1 before you recalculate the average, or you need to restructure your loop such that the examScore != SENTINAL check is done between reading and recalculating the average.
Also, strictly speaking, there is no need to make all the averaging calculations while the loop is still running. You can save the average = sumOfScores / sumOfExams; line until after the loop has finished. Just a thought.
As Paul R said, you also have the incorrect function prototype for your main function. Valid prototypes for the main function can be found here

Get program to return an error message and return to start of program if value entered is outside range

I'm a complete beginner with C and am currently trying to write a program where the user can enter results from football league games and calculate the teams' scores after each game.
There are 6 teams in the league and the user is required to choose a team at the start of the program in order to input a score for that team. What I would like to do is have the program return an error message if the user enters a value that is not between 1 and 6.
I've tried two different approaches but I'm not sure if either are in the right direction. One approach is shown below for the home team.
#include <stdio.h>
int main(void)
{
int h=0; /*Home team number*/
int a=0; /*Away team number*/
int hgoals=0; /*Goals scored by home team*/
int agoals=0; /*Goals scored by away team*/
/*User inputs home team number*/
printf("Home team number: ");
scanf_s("%d",&h);
/*Returns error message if home team number is not between 1 & 6*/
if(1<!h<!6){
printf("Please enter a number between 1 & 6\n");
}
return 0;
}
The other idea I had was to use an if statement where if the number entered is between 1 & 6 then nothing would happen, and use else to print the error message if the number is not between 1 & 6, but I'm not sure how to make an if statement that does nothing. I'm also thinking that I would have to put the entire program inside a loop to get it to restart if the number is not between 1 & 6.
Any help is appreciated!
Change the condition in the if statement :
if(h < 1 || h > 6)
printf("Please enter a number between 1 and 6\n");

Too few arguments in function to call [C program]

So, I have an assignment due tomorrow night for my online C programming class, and I am having some problems with my coding at the moment. I have brought the code to my teacher, but she doesn't seem to understand that she is being paid to teach me, not tell me that something is wrong with my code. I would appreciate if someone could take a look at the code and help me fix it. Code is located below. The location where I get my error is in main when calling the printtripSummary.
#include <stdio.h>
void welcomeMessage();
void askuserForInput();
void printtripSummary(float avgMiles, float minCost, float maxCost, float travelMiles);
int main()
{
/* Call the functions */
welcomeMessage();
askuserForInput();
printtripSummary();
printf("\nThank you, please drive safely and have a nice trip!\n");
return 0;
}
void welcomeMessage()
{
printf("Welcome to the Trip Planner!\n");
printf("So you are ready to take a trip? Let me help you plan for\n");
printf("your fuels costs and required stops to fill up your tank.\n");
printf("============================================================\n");
printf("Please provide answers to the prompts below and I will\n");
printf("display a summary for you when I have computed the results.\n");
printf("============================================================\n");
}
void askuserForInput()
{
float avgMiles, minCost, maxCost, travelMiles;
do{
printf("Please input your car's average miles per gallon (enter 0 to quit)>> ");
scanf_s("%f", &avgMiles);
if (avgMiles == 0)
break;
printf("Please tell me the range of fuel costs you expect to pay (per gallon>>)\n");
printf("The lowest per gallon cost of fuel is>> ");
scanf_s("%f", &minCost);
printf("The highest per gallon cost of fuel is>> ");
scanf_s("%f", &maxCost);
printf("Please tell me how many miles you plan to travel>> ");
scanf_s("%f", &travelMiles);
printtripSummary(avgMiles, minCost, maxCost, travelMiles);
} while (avgMiles != 0);
}
void printtripSummary(float avgMiles, float minCost, float maxCost, float travelMiles)
{
float avgGal, mingasPrice, maxgasPrice;
do{
avgGal = travelMiles / avgMiles;
mingasPrice = avgGal * minCost;
maxgasPrice = avgGal * maxCost;
printf("You will be required to purchase %.2f gallons of fuel.\n", avgGal);
printf("The price will range between %2f and $%.2f.\n", mingasPrice, maxgasPrice);
} while (avgMiles != 0);
}
Comment out the function call in main like this (Line 13):
//printtripSummary();
Because you call the function already in askuserForInput(); and this function get called in main
OR if you want to call the function also in main your have to pass the required arguments which are:
(float avgMiles, float minCost, float maxCost, float travelMiles)
Also you have a endless loop in the function printtripSummary(); Because you have a do...while loop which checks if avgMiles != 0, but since your not changing the value of avgMiles in this loop it's endless!
On line 13 you're calling the printtripSummary function without passing any arguments to it. You have to provide the 4 arguments the function definition specifies (avgMiles, minCost, maxCost, travelMiles).

Resources