This is my first attempt at C++, following an example to calculate a tip through a console application. The full (working code) is shown below:
// Week1.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
// Declare variables
double totalBill = 0.0;
double liquour = 0.0;
double tipPercentage = 0.0;
double totalNoLiquour = 0.0;
double tip = 0.0;
string hadLiquour;
// Capture inputs
cout << "Did you drink any booze? (Yes or No)\t";
getline(cin, hadLiquour, '\n');
if(hadLiquour == "Yes") {
cout << "Please enter you booze bill\t";
cin >> liquour;
}
cout << "Please enter your total bill\t";
cin >> totalBill;
cout << "Enter the tip percentage (in decimal form)\t";
cin >> tipPercentage;
// Process inputs
totalNoLiquour = totalBill - liquour;
tip = totalNoLiquour * tipPercentage;
// Output
cout << "Tip: " << (char)156 << tip << endl;
system("pause");
return 0;
}
This works fine. However, I want to move:
cout << "Please enter your total bill\t";
cin >> totalBill;
to be the first line under:
// Capture inputs
But when I do the application breaks (it compiles, but just ignores the if statement and then prints both cout's at once.
Im scratching my head becuase I cant understand what's going on - but I'm assuming I'm being an idiot!
Thanks
Try this
// Capture inputs
cout << "Please enter your total bill\t";
cin >> totalBill;
cin.clear();
cin.sync();
See c++ getline() isn't waiting for input from console when called multiple times
Or, better yet don't use getline at all:
cout << "Please enter your total bill\t";
cin >> totalBill;
cout << "Did you drink any booze? (Yes or No)\t";
cin >> hadLiquour;
totalBill is a number, i.e. the program "consumes" everything from your input that is a number. Let's say you entered:
42.2[RETURN]
The 42.2 gets copied into totalBill. The [RETURN] doesn't match, and remains in the input buffer.
Now, when you call getline(), the [RETURN] is still sitting there... I am sure you can figure out the rest from there.
Cin doesn't remove the newline character from the stream or do type-checking. So using cin>>var; and following it up with another cin >> stringtype; or getline(); will receive empty inputs. It's best practice to NOT MIX the different types of input methods from cin.
[for more informations see link]
you may change your code as below :
cout << "Please enter your total bill\t";
getline(cin, hadLiquour); // i used the hadLiquour string var as a temp var
// so don't be confused
stringstream myStream(hadLiquour);
myStream >> totalBill;
Related
I am trying to ask the user to enter the names of 3 of their friends, however, it only asks one question and writes the answer from my first one in the second and third.
#include <iostream>
using namespace std;
int main()
{
char first_name;
cout << "Please enter a name: ";
cin >> first_name;
cout << first_name << endl;
char second_name;
cout << "Please enter a name: ";
cin >> second_name;
cout << second_name << endl;
char third_name;
cout << "Please enter a name: ";
cin >> third_name;
cout << third_name << endl;
return 0;
}
You should probably be using string in your code to take the input of names. In names you are probably passing more than one character. The first one is read by first_name and any further character will be read by the following character, specifically cin>>second_name and cin>>third_name would read the 2nd and 3rd character of your input.
char a;
char b;
cin>>a; //will only read one character and stop
cin>>b; //will read the second character of the input...
//be that after pressing enter(a Enter b) or continuous input (ab)
cout<<a<<" "<<b; //will output 1st and 2nd character only
This will happen even if you don't press the Enter key explicitly and this is why your program uses the answer of first question(which is probably more than 1 character since it is a name) in your code as the answer to 2nd and 3rd questions as well.
So for your purpose, you are better of using string to take input from the users.
Hope this clears your doubt !
You tried to hold a lot of chars (one word) in one char who can hold only one char.
#include <iostream>
#include <string> // We need a string, container to hold a chars. Something like array of chars but have a few difference.
using namespace std; // You should avoid using this but in that short code this doesn't matter
int main()
{
// You don't need separate container for this code
// Then we create one container to holds all of inputs
string input;
cout << "Please enter a name: ";
cin >> input; // Put input from user in our input(string)
cout << input << endl; // Print input
// Next code is the same as above
cout << "Please enter a name: ";
cin >> input;
cout << input << endl;
cout << "Please enter a name: ";
cin >> input;
cout << input << endl;
return 0;
}
I special avoided a few elements like using function because this must be simple as possible.
I am trying to create a program which obtains names and test scores and places them into separate vectors. I am using getline() so I can get both first and last names. However, whenever I use the below code every name after the first loses its first letter. So, if the input for names was John Smith, Jane Smith, Jacob Smith, etc. The program outputs John Smith, ane Smith, acob Smith,... I tried taking out the cin.ignore()'s but then the program runs through after the first entry. I also tried creating separate functions for obtaining the names and scores, but this did not work either. Any advice or help would be appreciated.
int main() {
string test_taker;
int num_of_students = 0;
cout << "How many students took the exam? ";
cin >> num_of_students;
int starting = 0;
vector <double> score_list_us(num_of_students);
vector <string> name_list_us(num_of_students);
vector<double> score_list_sorted(num_of_students);
vector<string> name_list_sorted(num_of_students);
for (int i =0; i < num_of_students; i++) {
cout << "Student #" << i + 1 << " Name: ";
cin.ignore();
getline(cin, name_list_us[i]);
cout << "Student #" << i + 1 << " Score: ";
cin >> score_list_us[i];
cin.ignore();
}...
Problem: Missing character
See that cin.ignore(); right in front of getline(cin, name_list_us[i]);? Guess what it does.
On the first pass through the loop that cin.ignore(); eats the newline left by cin >> num_of_students; Every other time through the loop there is no newline to be eaten, so it eats part of your data.
Solution
Always put ignore()s, if you can't avoid them entirely, AFTER the operation that left the garbage you want gone. If you put ignore() before another operation, sooner or later you're going to hit that operation without garbage in the stream. In this case you hit it sooner.
Next, you want to ignore() everything up to and including the newline. Anything the user typed in after the input we want is garbage and should be discarded. Otherwise ignore() takes out a space character or something equally useless and leaves the newline for getline to trip over. I'll leave it to an old friend to explain what you need to do.
Specifically, use
cin.ignore(numeric_limits<streamsize>::max(), '\n');
So
int main() {
string test_taker;
int num_of_students = 0;
cout << "How many students took the exam? ";
cin >> num_of_students;
// ignore after
cin.ignore(numeric_limits<streamsize>::max(), '\n');
int starting = 0;
vector <double> score_list_us(num_of_students);
vector <string> name_list_us(num_of_students);
vector<double> score_list_sorted(num_of_students);
vector<string> name_list_sorted(num_of_students);
for (int i =0; i < num_of_students; i++) {
cout << "Student #" << i + 1 << " Name: ";
// not before
getline(cin, name_list_us[i]);
cout << "Student #" << i + 1 << " Score: ";
cin >> score_list_us[i];
// because this guy eats the newlines
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
I have to prompt the user to enter their name and their height using two separate inputs, one for feet and one for inches. Then I have to display what they entered. Ex: Name, you are x feet y inches tall. The program I wrote runs but it's not working as intended. After I write an input for the first question which is the name, the program skips the other questions and ends the program.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
int name;
int f;
int i;
// Start: Enter Name
cout << "What is your name?" << endl;
cin >> name;
// Enter height
cout << "How many feet tall are you tall?" << endl;
cin >> f;
// Enter inches
cout << "How many inches tall are you after feet?" << endl;
cin >> i;
// End: All info entered
cout << name << " you are " << (f) << " feet " << (i) << " inches tall." << endl;
system("pause");
return 0;
}
First and most importantly, you should change the type of name from int to string. Your current program tries to read your input to name as a number and not text.
Now, if your program is still not working as intended, make sure when you are typing in input for name there is no white-space (spaces, tabs, etc.) in between the name you are trying to input. For example, the input of John would be fine, but John Smith would not. This is because the >> operator when used with cin values all white-space the same. This means that pressing the space bar is the same as pressing the enter key to your program. If you are trying to input a full name, look into using getline to read input up until the enter key is pressed.
Getline Example:
cout << "What is your name?";
getline (std::cin,name);
Summary:
Change int name; to string name;. If you need to read multiple words for the name use getline.
I am trying to write code that will loop and input user input to a class and print out a chart. This is my main method:
int main()
{
Company productMatrix;
int inputNumber = 0;
cout << "enter the salesman id or -1 to quit." << endl;
cin >> inputNumber;
while(inputNumber != -1)
{
int salesman = inputNumber;
cout << "enter the product id." << endl;
cin >> inputNumber;
int product = inputNumber;
cout << "enter the amount sold." << endl;
cin >> inputNumber;
double dollarValue = inputNumber;
productMatrix.inputSales(salesman, product, dollarValue);
cout << "enter the salesman id or -1 to quit." << endl;
cin >> inputNumber;
}
productMatrix.printChart();
cout << "Goodbye!";
return 0;
}
when I run the program, it will let me input one set of data and then loop forever without waiting for me to stop. This is what it looks like:
enter the salesman id or -1 to quit.
3
enter the product id.
2
enter the amount sold.
55.99
enter the salesman id or -1 to quit.
enter the product id.
enter the amount sold.
enter the salesman id or -1 to quit.
enter the product id.
enter the amount sold.
// etc...
I'm guessing there is something wrong with my loop. How can I fox this?
The problem is with following line.
double dollarValue = inputNumber;
inputNumber is a integer type and dollar value is a float. So there is a type mismatch. You can create another variable like dollarInput and store the dollar value there
You're writing a double 55.99 to an integer, so cin takes 55 and it has '.' in the buffer which is always !=-1 but never gets read into as integer.
inputNumber is an int. But you entered a value (55.99) that can not be interpreted as an int. This put cin into an error state. Until the error is cleared, all future operations with cin fail. So it doesn't wait for your input, and the variables retain their values, and you can never get that -1 that the loop needs to terminate.
To check for an error, just use a plain old if statement:
if (cin) {
// cin is okay
}
else {
// cin is not okay
}
You can also be a little more concise and put your input operation directly in an if statment:
if (cin >> inputNumber) {
To clear the error:
cin.clear();
You will also probably need to clear the input stream, otherwise the erroneous input will remain in the input buffer, and cin will just try to read it again:
cin.ignore(); // discard one character from the input buffer
// or
cin.ignore(N); // discard N characters from the input buffer
Anyway, that's the cause of the infinite loop. But if you had just input directly into a double, instead of an int, you wouldn't have seen this issue. Isn't that what you want anyway?
To add to prajmus's answer, you can see the additional 'junk' in the input stream by adding the following 'cin' read:
...
double dollarValue = inputNumber;
productMatrix.inputSales(salesman, product, dollarValue);
cout << "enter the salesman id or -1 to quit." << endl;
double myDbl;
cin >> myDbl;
cout << "read the following double:" << myDbl << endl;
...
The added "cin >> myDbl" will read the '.99' from the input stream and the added cout will yield:
0.99
I am completing a lab assignment where the user is prompted for the type if fish they wish to order and to enter the price per pound. The user needs to be prompted for the type of fish and the price two times before the report prints.
The problem is that the program ends before the first instance of the loop has completed. (The way the code is written the titles on the report will print twice, but that was in the instructions.)
The code is below and any assistance is greatly appreciated.
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
float price;
string fishType;
int counter = 0;
// Change the console's background color.
system ("color F0");
while (counter < 3){
// Collect input from the user.
cout << "Enter the type of seafood: ";
cin >> fishType; // <------ FAILS AT THIS POINT. I GET THE PROMPT AND AT THE "ENTER" IT DISPLAYS THE REPORT
cout << "Enter the price per pound using dollars and cents: ";
cin >> price;
counter++;
}
// Display the report.
cout << " SEAFOOD REPORT\n\n";
cout << "TYPE OF PRICE PER" << endl;
cout << "SEAFOOD POUND" << endl;
cout << "-------------------------------" << endl;
cout << fixed << setprecision(2) << showpoint<< left << setw(25)
<< fishType << "$" << setw(5) << right << price << endl;
cout << "\n\n";
system ("pause");
return 0;
}
The new line character will not have been consumed by the read, using std::istream::operator>>(float), of the price:
cin >> price; // this will not consume the new line character.
The presence of the new line character during the next read, using operator>>(std::istream, std::string)), into fishType:
cin >> fishType; // Reads a blank line, effectively.
and then the user input that was intended to be the next fishType will be read (and fail to be) by the price as it will not be a valid float value.
To correct, ignore() until the next new line character after the read of the price. Something like:
cin.ignore(1024, '\n');
// or: cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Always check the status of input operation to determine if they were successful or not. This is easily achieved:
if (cin >> price)
{
// success.
}
If the fishType can contain spaces then using operator>>(std::istream, std::string) is not appropriate as it will stop reading at the first whitespace. Use std::getline() instead:
if (std::getline(cin, fishType))
{
}
When the user enters input a new line character will be written to stdin, i.e cin:
cod\n
1.9\n
salmon\n
2.7\n
On first iteration of the loop:
cin >> fishType; // fishType == "cod" as operator>> std::string
// will read until first whitespace.
and cin now contains:
\n
1.9\n
salmon\n
2.7\n
then:
cin >> price; // This skips leading whitespace and price = 1.9
and cin now contains:
\n
salmon\n
2.7\n
then:
cin >> fishType; // Reads upto the first whitespace
// i.e reads nothin and cin is unchanged.
cin >> price; // skips the whitespace and fails because
// "salmon" is not a valid float.