How get cin to stop skipping? [duplicate] - c++

This question already has an answer here:
C++ CIN cin skips randomly
(1 answer)
Closed 8 years ago.
Sorry, I dont know how to ask this better, I'm a really novice programmer and I'm not looking for you to do my homework, but I want to understand why this keeps happening.
int inputScores(string names [], double scores [])
{
int count = 0; // counter variable for number of student records in array
char again; // To check if user has more data
do
{
cout << "Enter student's name: ";
getline(cin, names[count]);
cout << "\nEnter student's score: ";
cin >> scores[count];
count++;
cout << "\nDo you have more student records to enter?(Y/N): ";
cin >> again;
}while(again == 'y' || again == 'Y');
when I run this code and call the function this keeps happening and I dont know how to fix it:
Enter student's name: Arthur
Enter student's score: 100
Do you have more student records to enter?(Y/N): y
Enter student's name:
Enter student's score:
it skips the "enter student's name question" (doesnt let me type anything) and goes straight to the next question.

The reason the program does not wait for you to enter the student's name is there is a \n still left in the input stream after you read again in the line:
cin >> again;
When the program reaches:
getline(cin, names[count]);
it just reads the an empty line and moves on to the next line.
You need to use:
int maxCharsToIgnore = 100; // This seems large enough
// for your use case.
cin.ignore(maxCharsToIgnore,'\n');
right after
cin >> again;

Related

Repeatedly non-stop output when I input char into int variable [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 months ago.
Improve this question
The folowing code tells user to input their age, it is set to be input interger between 0 and 120, it is capable to deal with wrong input like 'M' or 133 or -1. Warning message goes like this:Warning message
case 1: // input age
cout << "Enter your age: ";
cin >> age;
if(age <= 0 || age > 120){ // if the input type or number was wrong, it goes here
while(1){
cout << "Invalid input! Please enter again" << endl << ">>>";
age = -1;
cin >> age;
if(age > 0 && age <= 120) {break;}
}
}
However, it'll go wrong if I input something like \ or [.
Repeating Warning message
How can I solve this?
By emptying the keyboard buffer before a new entry.
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int age;
cout << "Enter your age: ";
cin >> age;
while(age <= 0 || age > 120)
{
cout << "Invalid input! Please enter again" << endl << ">>>";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin >> age;
}
return 0;
}
lets walk through this.
You type in something wrong and enter the if clause.
In here you enter the while loop and ask the user again for a input. This input is instantly answered because there is still something in the input stream.
Therefore you need to flush the cin stream before asking again for an input (You can place the flush in for example line 4).
You should be able to clear the stream with a command like this:
How do I flush the cin buffer?
Unfortunately I'm not able to test that out by myself but you can give it a try and I hope it helps!

Having difficulty obtaining double after using getline() in for loop

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');
}

c++ loop runs forever without waiting for input

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

C++ Noobie - Why does moving these lines break my application?

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;

How do I use iostream cin properly?

This may at first seem like an odd question, but when a cin request is made, if it receives the wrong type it still continues but the status of cin changes.
How do I loop until cin is OK, e.g. when I ask for a number it "accepts" a string if no extra code is given e.g. a loop?
Finally when I use cin multiple times in a row it does the first cin as expected but then skips the rest; how do I fix this? If you need more information just ask in a comment.
// Example
cout << "Enter a number: ";
cin >> num; // A string is given
cout << "Enter another number: ";
cin >> num2;
In the example above the string would be kinda accepted and the second cin would most likely skip for some reason. I had a while ago find the answer to this question but I lost the snippet of the loop I used so :/
example:
int value;
while(!(cin >> value))
{
cin.clear();
cin.ignore(); // eat one character
}
while(!(cin >> value))
{
cin.clear();
cin.ignore(10000,'\n'); // eat the rest of the line
}