getline() error in C++ when using for loop - c++

I had to write a program to calculate average speed of a car during a trip and I have to prompt the user for the names of the two cities that they were traveling between. That program worked, but the next program we had to write is an addition to the last one, in which the user is prompted for how many times the program should run. I declared a new variable for the number of times the users needs the program to run. However when the program enters the loop it skips the first getline() method (asking for the origin city) and skips directly to the second getline() (method asking for the destination city). I have tried clearing the buffer and declaring the loop differently, but whatever I do the string is still read into the program as an empty string. Just wondering if I made a mistake on something or if I cannot use getline() in this instance.
Using C++ and Codeblocks IDE with the GNU Compiler (I've tried other compilers too)
Anyhow here is the code.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
//Declare Variables
string orgcity = "";
string destcity = "";
int hours = 0;
double minutes = 0.0;
int hoursmin = 0;
int minutesmin = 0;
int minutesmax = 60;
double dist = 0.0;
double totalhours = 0.0;
double avespeed = 0.0;
double num1 = 0;
cout << "How many times would you like to calculate the average speed: ";
cin >> num1;
for(num1; num1 > 0; --num1)
{
//Collect Data
cout << "Enter the city of origin: ";
getline(cin, orgcity);
cout << "Enter the destination city: ";
getline(cin, destcity);
//If Statements and Loops...Start here
do {
cout << "Enter the number of hours spent in travel: ";
cin >> hours;
if (hours < hoursmin)
cout << " Invalid number of hours - must be >= 0" << endl;
} while (hours < hoursmin);
do {
cout << "Enter the number of minutes spent in travel: ";
cin >> minutes;
if (minutes >= minutesmax){
cout <<" Invalid number of minutes - must be in range 0..59" << endl;
}
if (minutes <= minutesmin) {
cout << " Invalid number of minutes - must be in range 0..59" << endl;
}
} while (minutes >= minutesmax);
//End Here
cout << "Enter the distance (in miles) between the two cities: ";
cin >> dist;
cout << endl;
//Formula and Final Prompt
totalhours = (hours + (minutes / 60.0));
avespeed = dist / totalhours;
cout << "The average speed of the vehicle traveling" << endl;
cout << "between " << orgcity << " and " << destcity << " is " << fixed << setprecision(2) << avespeed << " miles per hour." << endl;
cout << "-------------------------------------------------------------------------------" << endl;
}
return 0;
}

When you read the number of times the loop should be run, the input operator reads the number, but leaves the newline in the buffer. This means that the first call to getline reads that single newline and nothing more.
To make sure you skip anything after that number, up to and including the newline, you can use e.g.
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

Related

Skips the first prompt instead [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 4 years ago.
Good day,
I was writing this code for a school project, but after compiling and executing it, after hitting yes, I was unable to enter a name.
I am not sure why this is happening, happened to both codeblocks and vs community.
I've tried adding cin.ignore(); below getline(cin, customer) and it kinda works but I am not able to enter the name of a business. If I put cin.ignore() on both, the enter number field will be skipped and it will go directly to the results.
I will attach an image below (without using cin.ignore)
#include "pch.h"
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
string input;
cout << "hello, press yes to start or no to cancel \n";
cin >> input;
if (input == "no")
{
cout << "have a nice day \n";
}
else if (input == "yes")
{
string customer;
string address;
int user_enter_number;
const double pc = 0.05 * 10;
double amount, abacus, price; // abacus = AMOUNT
time_t now; // rawtime
struct tm nowlocal;
cout << "Please enter your name " << endl;
getline(cin, customer); ` when executing, I was not able to type my
name and instead was skipped and went to
enter the store's name.`
cout << "Please enter the store's name \n";
getline(cin, address);
cout << "Please enter the number you would like to buy, the range is
from 00 - 99 \n";
cin >> user_enter_number;
cout << "Please enter the amount you wish to spend ($): \n";
cin >> amount;
abacus = amount * pc;
price = amount;
now = time(NULL); // obtains the time from the operating system
nowlocal = *localtime(&now);
cout << customer << " you have bought this number: " <<
user_enter_number << endl;
cout << "you have bought this pcs: " << amount / 0.05 << endl;
cout << "this ticket was bought on: " << nowlocal.tm_mday << "/" <<
nowlocal.tm_mon + 1 << "/" << nowlocal.tm_year + 1900 << endl;
cout << "at this time: " << nowlocal.tm_hour << ":" << nowlocal.tm_min << ":" << nowlocal.tm_sec << endl;
srand(time(NULL));
int min = 00;
int max = 99;
int num = (min + (rand() % (int)(max - min + 1)));
cout << "the winning number is: " << num << endl;
if (num == user_enter_number)
{
cout << customer << " You have won" << amount << "Please visit your
nearest store to collect! \n";
}
else
{
cout << "Try again next time! \n";
}
return 0;
}
The first line of input is a line. Use getline for that too.
cin >> input;
Leaves the newline in the buffer.
getline(cin, customer);
Only gets to read the newline from the first input.

How can I do this without arrays or vectors only using loops

I am almost done with this project just stuck on this last part. Really need help I've reach out to teacher not getting a response. I want to display which complex enter has the highest rent total. Right now I have a double named currentRentAmount which keeps a running total after each loop it reset. So the issue is if the first complex enter was the highest rent collected complex enter it loses that value because its reset to 0. I feel so close yet so far a way. I cant use vector/ array because we technically haven't learn it yet.
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
ofstream outputFile;
outputFile.open("rentfile.txt");
int numComplex, numMonths;
double rent, totalAllRent = 0; //// Accumulator for total scores
string nameComplex;
string highNameComplex;
double averageRent;
double highestComplexRent = 0;
double currentRentAmount = 0;
double previousRentAmount = 0;
//set up numeric output programing
cout << fixed << showpoint << setprecision(1);
cout << "How many complexes will you enter?";
cin >> numComplex; //number of complexes enter
cout << "How many months of rent will you enter complex?";
cin >> numMonths; //number of months of rent enter
for (int complex = 1; complex <= numComplex; complex++)
{
cout << "Enter Complex Name ";
cin >> nameComplex;
outputFile << nameComplex << " ";
for (int months = 1; months <= numMonths; months++)
{
cout << "Enter Rent " << months << " for ";
cout << " Complex " << complex << ": ";
cin >> rent;
totalAllRent = totalAllRent + rent;
averageRent = totalAllRent / numComplex;
outputFile << rent << endl; //write data to output file
currentRentAmount = currentRentAmount + rent;
cout << currentRentAmount << endl;
if (currentRentAmount > highestComplexRent)
{
currentRentAmount = highestComplexRent;
}
}
currentRentAmount = 0;
}
outputFile.close(); //close the file
ifstream inputFile;
inputFile.open("rentfile.txt");
cout << "Complex Monthly rent Collected per Complex " << endl;
while (inputFile >> nameComplex)
{
for (int i = 0; i < numMonths; i++)
{
inputFile >> rent;
cout << nameComplex << " " << rent << endl;
if (rent == 0)
cout << "Warning one of the complexes submitted zero rent for one of the months " << endl;
}
}
cout << "Total rent collected for the company = " << totalAllRent << endl;
cout << " Average Monthly rent collected for the company = " << averageRent << endl;
cout << highNameComplex << "collect the most rent = " << highestComplexRent << endl;
system("pause");
return 0;
}
First a friendly note; 'Complex number' means something very specific , you are talking about apartment complex numbers. However, when most people read complex number they think x+iy (think imaginary numbers)
Second , the problem you have is one of logic. You want to find the apt complex with the highest rent, but you seem to update the highest rent value in this condition.
if (currentRentAmount > previousRentAmount)
{
highestComplexRent = currentRentAmount;
}
Ask yourself why you are doing this , what happens in every iteration of the loop. IF currentRentAmount > previousRentAmount since previousRentAmount is always 0.Effectively, this means, if the value of current rent is greater than 0 highest rent is set to current rent.
What you want here is:
1. Make sure highestRentAmount is set to 0 outside of the loops.
2. The if check should be if(currentRentAmount > highestComplexRent) (think through why this will work, I can tell you the answer, but just think about it for a second, its much better to arrive at it yourself)
Good luck
You can use a variable maxComplexRent to keep the track of complexRent.
double maxComplexRent = 0.0;
for (int complex = 1; complex <= numComplex; complex++)
{
cout << "Enter Complex Name ";
cin >> nameComplex;
outputFile << nameComplex << " ";
for (int months = 1; months <= numMonths; months++)
{
cout << "Enter Rent " << months << " for ";
cout << " Complex " << complex << ": ";
cin >> rent;
totalAllRent = totalAllRent + rent;
averageRent = totalAllRent / numComplex;
outputFile << rent << endl; //write data to output file
currentRentAmount = currentRentAmount + rent;
cout << currentRentAmount << endl;
}
//Here
maxComplexRent = maxComplexRent>currentRentAmount? maxComplexRent:currentRentAmount;
currentRentAmount = 0;
}
Few suggestions here:
It does not use the correct variable:
if (currentRentAmount > previousRentAmount)
should be changed to
if (currentRentAmount > highestComplexRent)
This line should be moved out to the outer loop (although it is unused):
averageRent = totalAllRent / numComplex;
Remove the unused variables.
if statement was wrong able to fix
if (currentRentAmount > highestComplexRent)
{
highestComplexRent = currentRentAmount;
}

How can I get user input to exit a loop?

I have a problem with my code, every time I loop it with the answer 'y'(Yes) it loops to infinity?
I'm trying to make a loan calculator and every time the user is done calculating with a transaction and wants to reset, and do another calculation if he enters in a value 'y', and if he enters 'n' the program will end.
Here's my code so far:
#include <iostream>
#include <string>
#include <iomanip>
#include <cmath>
using namespace std;
int main() {
char ans = 'y';
do {
string name;
int Months;
int n;
double LoanAmount, Rate, MonthlyInterest, TotalLoanAmount, MonthlyAmortization, OutstandingBalance;
cout << fixed << showpoint;
cout << "Enter Name of Borrower: ";
getline(cin, name);
cout << "Enter Loan Amount: ";
cin >> LoanAmount;
cout << "Enter Number of Months to Pay: ";
cin >> Months;
cout << "Enter Interest Rate in Percent(%): ";
cin >> Rate;
cout << setprecision(2);
MonthlyInterest = LoanAmount * Rate;
TotalLoanAmount = LoanAmount + (MonthlyInterest * Months);
cout << "Monthly Interest: " << MonthlyInterest << endl
<< "Total Loan Amount with interest: " << TotalLoanAmount << endl;
cout << setw(100)
<< "\n\tSUMMARY OF OUTSTANDING INSTALLMENT" << endl
<< "\tName of Borrower: " << name
<< "\n\nMonth\t\tMonthly Amortization\t\tOutstanding Balance"
<< "\n";
for(n = 1; n <= Months; n++) {
MonthlyAmortization = TotalLoanAmount / Months;
OutstandingBalance = TotalLoanAmount - MonthlyAmortization;
cout << n << "\t\t" << MonthlyAmortization << "\t\t\t" << n - 1 << OutstandingBalance << endl;
}
cout << "\nEnd of Transaction";
cout << "Do you want to compute another transaction?[y/n]?" << endl;
cin >> ans;
}
while(ans == 'y');
}
After your cin>>ans, add these two lines :
cin.clear();
cin.sync();
That usually fixes a lot of the infinite looping problems I get with cin.
Also, I would recommend against initializing ans as 'y' when you declare it. I don't think this is causing you problems but it's an uncessesary thing.
You seem to expect pressing y and enter to register as only 'y'. If you want to get the input of just one character have a look at std::cin.get(char)

C++ Input and Output problems

My problem is that when i compile and run the program, the hours doesnt have "hours" listing 1,2,3 as the loop continues and also the loop calculation is the same for each line.
this is what the program looks like
http://postimg.org/image/htk194eah/
the calculation is wrong and the hours is suppose to say 1,2...5
I would like it to look something like this
http://postimg.org/image/pnkvab1j1/
this is what i have so far:
int main()
{
// Variables
int speed;
int time;
int distance;
// Obtain the speed
cout << "Please input the speed of the vehicle " ;
cin >> speed;
while(speed < 0) // while statement
{
cout << "Please refrain from using a negative number ";
cin >> speed;
}
cout << "Please enter the time, represented in hours, travelled" <<endl;
cin >> time;
// Obtain the time
while(speed < 1)
{
cout<< "Please use a number greater than 1 " <<endl;
cin >> time;
}
// Calculation
distance = speed * time;
cout << endl;
cout << "Hour(s) " << "\t" << "Distance Travelled" << endl;
cout << "____________________________________________" << endl;
// "for" Loop statement
for(int count =1; count <= time; count++)
{
cout << " " << "\t\t" << speed*time << endl;
}
system ("PAUSE");
return 0;
}
When you print in your for loop, speed = 20 and time = 5 always, so it always prints 100 (in the example you give).
You want to be printing speed*count (in this case).
Again you print "" for the hours, which is an empty string, you want to be printing count.
cout << count << "\t\t" << speed*count << endl;
Here is the correct program. Your program was very good. But you have a very small mistake.
#include<iostream.h>
main()
{
// Variables
int speed;
int time;
int distance;
// Obtain the speed
cout << "Please input the speed of the vehicle " ;
cin >> speed;
while(speed < 0) // while statement
{
cout << "Please refrain from using a negative number ";
cin >> speed;
}
cout << "Please enter the time, represented in hours, travelled ";
cin >> time;
// Obtain the time
while(speed < 1)
{
cout<< "Please use a number greater than 1 ";
cin >> time;
}
// Calculation
cout << endl;
cout << "Hour(s) " << "\t" << "Distance Travelled" << endl;
cout << "____________________________________________" << endl;
// "for" Loop statement
for(int count =1; count <= time; count++)
{
cout << count << "\t\t" << speed * count << endl;
}
system ("PAUSE");
return 0;
}

Baseball Batting Average Program

I need help with a program for school. We had to write a program that asks the user for information about a baseball player. We need to calculate the players batting average with their games played, number of times at bat and number of hits. I am running into an issue where my computation for the average is outputting a set number and not performing any computations. I am entering whole integers for all the variables that are used for calculation. So i would input numbers like 1, 4 , 10 etc... As the program stands the value my formula is setting itself equal to is 15903.876. All of my variables used for the average formula are declared as integers and the batting average itself is declared as a double. I have done some debugging my self and found that the computation messes up when it divides the number of times at bat by the number of hits. If anyone could help me figure out the issue i would appreciate it.
//libaries
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
class battingAverage
{
public:
string pName;
int nBats;
int tHits;
int gPlayed;
int gcalled;
double average;
double average1;
double playeraverage;
};
int main()
{
string numberPlayers;
int nplayers;
//enters the number of players the user wants to enter data for
cout << "Enter the number of players you want to enter data for: ";
cin >> numberPlayers;
cout << endl;
//converts the value of numberPlayers to nplayers
istringstream convert(numberPlayers);
//sets integer nplayers equal to the value of the string numberPlayers
if(! (istringstream(numberPlayers) >> nplayers) )
{
nplayers = 0;
}
cout << "This program calculates the batting average of baseball players.\nYou may enter data for " << nplayers << " players." << endl;
battingAverage ba[nplayers];
int index = 0;
//while statement to get data
while(index < nplayers)
{
cout << "Enter the players last name: " << endl;
cin >> ba[index].pName;
cout << "Enter the number of games the player played: " << endl;
cin >> ba[index].gPlayed;
cout << ba[index].gPlayed << endl;
cout << "Enter the number of games the player was called in for: " << endl;
cin >> ba[index].gcalled;
cout << ba[index].gcalled << endl;
cout << "Enter the number of times the player was at bat: " << endl;
cin >> ba[index].nBats;
cout << ba[index].nBats << endl;
cout << "Enter the number of time the player hit: " << endl;
cin >> ba[index].tHits;
cout << ba[index].tHits << endl;
if(ba[index].tHits > ba[index].nBats)
{
cout << "Enter a valid value for the number of times the player hit: ";
cin >> ba[index].tHits;
}
cout << endl;
index++;
}
//rounds average to 3 decimal places
cout << fixed << setprecision( 3 );
//average formula
ba[index].playeraverage = (ba[index].nBats / ba[index].tHits) * (ba[index].gPlayed / ba[index].gcalled);//error
cout << ba[index].playeraverage << endl << endl;//just temp line to check calculation of average.
ba[index].average = .000;
ba[index].average1 = .099;
while(ba[index].average < 1 && ba[index].average1 < .899)
{
ba[index].average +=.100;
ba[index].average1 += .1;
//prints chart
cout << setprecision( 1 ) << ba[index].average << "00" << setprecision( 3 ) << setw(12) << ba[index].average1 << endl;
}
cout << "1.000" << setw(12) << "1.000" << endl;
//version of system pause
cout << "\nPress enter to continue...";
cin.sync();
cin.ignore();
return 0;
}
On this line:
ba[index].playeraverage = (ba[index].nBats / ba[index].tHits) * (ba[index].gPlayed / ba[index].gcalled);//error
You have this expression:
(ba[index].nBats / ba[index].tHits)
Because both nBats and tHits are integers, you're using only integer math.
The answer will be an integer.
For example:
nBats = 10 & tHits = 3, you'd expect the expression to be 3.333.
But it would only be 3
To fix this, I recommend changing to:
((double)ba[index].nBats / ba[index].tHits)
Same thing again with the expression about gPlayed and gcalled.
Your value of index is wrong during the calculations.
I found this as soon as I put your code in a debugger and stepped through it, something you really should have done yourself.
You start with int index = 0;, and increment it as the user puts in each player's data.
At the end of the input-loop, index is now the same as the number of players.
(eg. if you had 5 players, index is now 5, and the player data is stored in ba[0], ba[1], ba[2], ba[3], and ba[4])
Note that at this point ba[5] is NOT valid data. But that is exactly where ba[index] is!
You do all your calculations on ba[index], which is invalid data, and you wonder why you get meaningless results?
I recommend you set index back to 0 before starting your calculations, and make another loop that does the necessary calculations for each player 0...4.