getline(cin, var) issue. Program ignores the command - c++

I have an issue with the code in line 23. (Please see code below)
When I use "cin >> studentNum"; I have no issue and the program reads the one string for the firstname, but if I want to gather more data using "getline(cin, studentNum)" to read more strings like the full name, the program just skips the command and asks for the score .
Why is that?
#include <iostream>
#include <string>
using namespace std;
int main()
{
int studentNum, testNum, i, j;
double sum, testScore, average;
string studentName;
i = 0;
// asking user for input
cout << "Please enter the number of students in this classroom: " << endl;
cin >> studentNum;
cout << "Now enter the number of tests each student has taken in this class: " << endl;
cin >> testNum;
while (i < studentNum)
{
cout << endl << "Now please enter the firstname of the student: " << endl;
cin >> studentName; //**My Problem is in this line ###########**
j = 0;
sum = 0;
while (j < testNum)
{
cout << "Please enter the score of each test, then hit enter: " << endl;
cin >> testScore;
sum += testScore;
j++;
}
i++;
}
}

It sounds to me that you need to use cin.ignore. You need to discard the linefeed character still present in the stream.
#include <limits>
// This is not a C++11 feature, works fine in C++98/03
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(std::cin, studentName);
By default, operator>> will skip leading whitespace, i.e. classifed by std::ctype. You can see that in a test program by turning this behavior off with unsetf(std::ios_base::skipws), that it will extract the whitespace. By using cin.ignore, you can simply discard it since it's undesirable. For more information, see cin and getline skipping input.

You should clear the state flag and flush the steram
cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
getline(cin, studentName);

Related

Which flag in cin turns to false when you enter a wrong type input [duplicate]

I want to check if the input is valid, but when i do run this code I see that it checks only input for charcters. If i input a float number it will take it and going to use like integer without fractional part.
#inclide <iostream>
using namespace std;
...
int n;
cout << "Your input is: "<<endl;
cin >> n;
while (cin.fail()) {
cout << "Error. Number of elements must be integer. Try again: " << endl;
cin.clear();
cin.ignore(256, '\n');
cin >> n;
}
...
`
So, how to make this code see if the input is float?
You can try to convert the input string to a int using a std::istringstream. If it succeeds then check for eof() (after ignoring blank spaces) to see if the whole input was consumed while converting to int. If the whole input was consumed then it was a valid int.
Something a bit like this:
int input_int()
{
int i;
// get the input
for(std::string line; std::getline(std::cin, line);)
{
// try to convert the input to an int
// if at eof() all of the input was converted - must be an int
if(!line.empty() && (std::istringstream(line) >> i >> std::ws).eof())
break;
// try again
std::cout << "Not an integer please try again: " << std::flush;
}
return i;
}
int main()
{
std::cout << "Enter an integer: " << std::flush;
std::cout << "i: " << input_int() << '\n';
}
Building on Raindrop7's solution, here's the full code to do what you need:
#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double m;
cout << "Your input is: "<<endl;
cin >> m;
while (cin.fail() || (m-floor(m)))
{
cout << "Error. Nubmer of elements has to be integer. Try again: " << endl;
cin.clear();
cin.ignore(256, '\n');
cin >> m;
}
int n = (int)m;
return 0;
}
Here's a sample output:
Your input is:
2.7
Error. Nubmer of elements has to be integer. Try again:
erer
Error. Nubmer of elements has to be integer. Try again:
2
The code below should be able to do what you are hoping to achieve:
#inclide <iostream>
using namespace std;
int n;
cout << "Your input is: "<<endl;
while (!(cin >> n) || cin.get() != '\n') {
cout << "Error. Number of elements must be integer. Try again: " << endl;
cin.clear();
cin.ignore(256, '\n');
}
The program asks the user to re-enter an integer if either of the following happens:
If the program is unable to extract an integer from the std::cin stream. (For example, when a character or string is entered by the user)
If, after an integer is extracted successfully, the next character in std::cin is not the new line '\n' character. (For example, when a number with a decimal point like 1.1 is entered, or when an integer followed by a character like 1a is entered.)

How can I have my array stop reading in characters when the enter key is pressed?

I am new to programming and I can't seem to figure out how to fix this problem. My assignment is very simple, to order two words alphabetically using only the strcmp function.
My program compiles and runs, but it doesn't progress until I fully fill the array with characters, but we are meant to be able to use words of different lengths.
Here is what I have written:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
int x;
char wordone[10] , wordtwo[10];
cout << "Please enter your first word: \n";
for(x=0; x<10; x++) cin >> wordone[10];
cout << "Please enter the second word: \n";
for(x=0; x<10; x++) cin >> wordtwo[10];
if(strcmp(wordone, wordtwo)<0)
{
cout << wordone << endl << wordtwo;
}
if ( strcmp( wordone,wordtwo)>0)
{
cout << wordtwo << endl << wordone;
}
else
{
cout << wordone << endl << wordtwo;
}
return 0;
}
And the output looks like this:
Please enter your first word:
help
me
please
Please enter the second word:
hello
how
`
#
àu0þ
I've been trying every combination I can think of, any help would be much appreciated!
For input. Use getline or directly take input.
Instead of this -
cout << "Please enter your first word: \n";
for(x=0; x<10; x++) cin >> wordone[10];
Possible solutions.
Do this -
char name[10];
cin>>name;
or do this
string s;
cin>>s; // simply take input like ordinary variable. Rember to #include<string>
or do this --
string s; // for getline this is must. Use string
getline(cin,s);

loop repeats without prompting the user again?

I have this snippets of code from my original long program, and as much as it looks simple, it doesn't work correctly! I am brand-new to c++ language, but I know in Java that would be the way to do it (Regardless of the syntax).
Simply put, this should ask the user for an input to answer the following multiplication (5*5), however, it should also check if the user entered a wrong input (not number), keep asking the user again and again... Somehow, it keeps running forever without taking a new input!!
I hope to get, not only an answer, but also a reason for such an error!
int main() {
int userAnswer;
bool isValidAnswer = true;
cout << 5 << " * " << 5 << " = ";
cin >> userAnswer;
cin.ignore();
do {
if (cin.fail()) { //user input is not an integer
cout << "Your answer is not valid! Please enter only a natural number: ";
cin >> userAnswer;
cin.ignore();
} else {
isValidAnswer = false;
}
} while (isValidAnswer);
return 0;
}
Well you need to clear the error state before accepting new input. Call cin.clear() then cin.ignore() before trying to read input again.
I would do something like.
cout << "Enter a number: ";
cin >> number;
while(cin.fail())
{
cin.clear();
cin.ignore(1000, '\n'); //some large number of character will stop at new line
cout << "Bad Number Try Again: ";
cin >> number;
}
First, cin.fail() is not going to adequately check if your answer is a natural number or not with the type set to int (could also be negative).
Second, your boolean isValidAnswer is really checking if it's is an invalid answer.
Third (and most importantly), as another answer suggests, you should put in cin.clear() to clear the failure state, and then followed by cin.ignore(), which will remove the failed string from cin.
Fourth, cin will only check if an int exists somewhere in the string. You'll need to perform your own string comparison to determine if the entire input is a int (see answer below, based on this answer).
Updated:
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
bool isNum(string line)
{
char* p;
strtol(line.c_str(), &p, 10);
return *p == 0;
}
int main() {
int userAnswer;
string input;
bool isInvalidAnswer = true;
cout << 5 << " * " << 5 << " = ";
while (isInvalidAnswer) {
if (!(cin >> input) || !isNum(input)) {
cout << "Answer is not a number! Please try again:\n";
cin.clear();
cin.ignore();
}
else {
userAnswer = atoi(input.c_str());
if (userAnswer < 0) { //user input is not an integer
cout << "Answer is not a natural number! Please try again:\n";
} else {
isInvalidAnswer = false;
}
}
}
cout << "Question answered!\n";
return 0;
}

How Can I avoid char input for an int variable?

The program below shows a 'int' value being entered and being output at the same time. However, when I entered a character, it goes into an infinite loop displaying the previous 'int' value entered. How can I avoid a character being entered?
#include<iostream>
using namespace std;
int main(){
int n;
while(n!=0){
cin>>n;
cout<<n<<endl;
}
return 0;
}
Reason for Infinite loop:
cin goes into a failed state and that makes it ignore further calls to it, till the error flag and buffer are reset.
cin.clear();
cin.ignore(100, '\n'); //100 --> asks cin to discard 100 characters from the input stream.
Check if input is numeric:
In your code, even a non-int type gets cast to int anyway. There is no way to check if input is numeric, without taking input into a char array, and calling the isdigit() function on each digit.
The function isdigit() can be used to tell digits and alphabets apart. This function is present in the <cctype> header.
An is_int() function would look like this.
for(int i=0; char[i]!='\0';i++){
if(!isdigit(str[i]))
return false;
}
return true;
If you want use user define function you can use the ascii/ansi value to restrict the char input.
48 -57 is the range of the 0 to 9 values
#include <iostream>
#include <climits> // for INT_MAX limits
using namespace std;
int main()
{
int num;
cout << "Enter a number.\n";
cin >> num;
// input validation
while (cin.fail())
{
cin.clear(); // clear input buffer to restore cin to a usable state
cin.ignore(INT_MAX, '\n'); // ignore last input
cout << "You can only enter numbers.\n";
cout << "Enter a number.\n";
cin >> num;
}
}
You need to check for cin fail
And
You need clear the input stream
See the following example.
It is tested in recent compilers
#include <iostream>
using namespace std;
void ignoreLine()
{
cin.clear();
cin.ignore();
}
int main(int argc, char const* argv[])
{
int num;
cout << "please enter a integer" << endl;
cin >> num;
while (cin.fail()) {
ignoreLine();
cout << "please enter a integer" << endl;
cin >> num;
}
cout << "entered num is - " << num << endl;
return 0;
}

C++ GetLine() Problem, Command Line Program

I am writing this program for my programming class and it has a bunch of stupid constraints like I must use nested if else statements and I have to use the cin.getLine() to get a players name. It is supposed to grab the name of each player and calculate their batting average.
This is not the entire program but up to the part where I am having an error. When I run this in a command prompt I can recieve the first name fine, but after that the second cin.getline() does not read any input. Suggestions?
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
char name1[100], name2[100], name3[100];
int numBat, numHit;
double avg1, avg2, avg3;
// Get Average for Player 1
cout << "What's Your Name? ";
cin.getline(name1, 100);
cout << "How many times have you been at bat? ";
cin >> numBat;
if(numBat < 0 || numBat > 25)
{
cout << "ERROR ::: Number of Times at Bat Cannot Be Less Than 0 or Greater Than 25. Run Program Again." << endl;
return 0;
}
else
{
cout << "How many times have you hit the ball? ";
cin >> numHit;
if(numHit < 0)
{
cout << "ERROR ::: Number Hit Cannot Be Less Than 0. Run Program Again." << endl;
return 0;
}
else
{
// Calculate Average for Player 1
avg1 = numHit / numBat;
// Get Average for Player 2
cout << "What's Your Name? ";
cin.getline(name2, 100);
cout << "How many times have you been at bat? ";
cin >> numBat;
cout << "How many times have you hit the ball? ";
cin >> numHit;
}
}
}
I think it's a buffer problem. Try to flush the cin before the second getline:
cin.clear(); // clear the buffer
cin.sync();
if that does not work, try something like this:
cin.ignore(256, '\n'); // ignore the endline and char(256)
After the getline, you need to output a newline using cout << endl;.
When you use
cin >> numBat;
It doesn't read the newline, so the next cin.getline() will read that and continue.
Use
cin >> numBat;
cin.ignore(80,'\n');