Error with input-validation using std::cin - c++

I have implemented this check in my program to determine if the input is of the right type or not, and if not it asks to re-write the input.
If the input is wrong it works just fine but, if the input is right, you need to write it again. How can I avoid this? (you can find an example here https://godbolt.org/z/KjoTbc)
#include <iostream>
#include <limits>
int main() {
int input;
std::cin >> input ;
while (!(std::cin >> input)) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Please, write an integer number\n";
};
}

You are not checking the first std::cin >> input ; and running while (!(std::cin >> input)), which asks input, unconditionally.
Remove the first unchecked reading and try this:
#include <iostream>
#include <limits>
int main() {
int input;
while (!(std::cin >> input)) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Please, write an integer number\n";
}
}

Related

C++ istream (cin) and problem with waiting for a ENTER key press

Please, is there a way I can wait for a single ENTER key press in all of the below cases? It works fine except when the std::getline() is used, which consumes the \n, and the ENTER needs to be pressed twice.
The code below works fine:
#include <iostream>
#include <limits>
using std::cout;
using std::cin;
using std::string;
void waitForENTERKeyPress();
int main ()
{
char c;
string s;
cout << "Enter c:"; cin >> c;
waitForENTERKeyPress();
cout << "Enter c:"; c = cin.get();
waitForENTERKeyPress();
cout << "Enter s:"; cin >> s;
waitForENTERKeyPress();
cout << "Enter s:"; std::getline(cin, s);
waitForENTERKeyPress();
return 0;
}
void waitForENTERKeyPress()
{
// Does not work with std::getline(...)
cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n');
cout << "Press an ENTER to continue...\n";
cin.get();
}
====[UPDATE]============================================
Let me rephrase what I am looking for: The way how to make the waitForENTERKeyPress() function working in both cases – with \n in the buffer, when cin operator >> or cin.get() is used and also in cases the std::getline() is used.
From what I understand it is not possible as there is not a way how to detect if the \n is still in the buffer or not.
I have tried to use cin.rdbuf()->in_avail(), but it always returns 0.

C++ program does not allow me to give a second input

I have two consecutive inputs, however, my program ends before allowing me to have my second input and just runs till the end, so:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<double>v1;
for(double temp1; cin >> temp1;)
v1.push_back(temp1);
cout << "input1";
vector<double>v2;
for (double temp2; cin >> temp2;)
v2.push_back(temp2);
cout << "input2";
return 0;
}
I will be given the opportunity for input in the first for loop, however, after that, it doesn't let me give a second input and just goes on to print "input2".
It is ok to use the fail state of std::cin this way. You just need to reset std::cin before it can be used again.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<double>v1;
for(double temp1; cin >> temp1;)
v1.push_back(temp1);
cin.clear(); //clear the error
cin.ignore(1000, '\n'); //ignore characters until we reach \n
cout << "input1";
vector<double>v2;
for (double temp2; cin >> temp2;)
v2.push_back(temp2);
cout << "input2";
return 0;
}
You could also #include <limits> and call
cin.ignore(numeric_limits<streamsize>::max(),'\n');
instead, to ignore unlimited characters until \n is reached.

Weird behavior when using cin.ignore and cin.clear CPP

I learned that cin.clear() clears the error flag, so the cin operations will work well, and cin.ignore() to extract characters from the stream.
So I tried this code:
#include <iostream>
#include <string>
int main()
{
std::string s;
std::cin >> s;
std::cout << s;
std::cin.clear();
std::cin.ignore(1000, '\n');
std::getline(std::cin, s);
std::getline(std::cin, s);
std::cout << s;
system("pause");
return 0;
}
It works well.
For three inputs:
I
AM
TRY
The output will be:
I
TRY
But if I change it to be:
#include <iostream>
#include <string>
int main()
{
std::string s;
std::cin >> s;
std::cout << s;
std::cin.clear();
std::cin.ignore(1000, '\n');
std::getline(std::cin, s);
std::cin.clear(); // New code
std::cin.ignore(1000, '\n'); // New code
std::getline(std::cin, s);
std::cout << s;
system("pause");
return 0;
}
I will need to enter four inputs!
How does it make any sense that when I add the code above, I will need to enter:
I
AM
NOW
TRY
To get the same output? For some reason it requires one input more.
Consider you intput I AM TRY NOW every time.
#include <iostream>
#include <string>
int main()
{
std::string s;
std::cin >> s;
std::cout << s; //-> outputs "I"
std::cin.clear();
std::cin.ignore(1000, '\n');//consumes all that follows "I"
std::getline(std::cin, s); //-> get the whole "I AM TRY NOW" inside s
std::cin.clear();
std::cin.ignore(1000, '\n'); //Your cin is empty (because you took the whole line with getline(), not just part of the line, the stream has no character left in it and this cin.ignore() call is the reason you need 1 more input, because calling cin.ignore() en empty stream does that.
std::getline(std::cin, s); //-> overwrites the previous std::getline(std::cin, s);
std::cout << s; //outputs the whole line : "I AM TRY NOW"
system("pause");
return 0;
}
Because you call cin.ignore(1000, '\n'); on an empty stream, you get one more input with the second code sample.
Try this
int main()
{
std::string s;
std::cin.ignore(1000, '\n'); // New code
system("pause");
}
It will require an input whereas this :
int main()
{
std::string s;
cin >> s;
std::cin.ignore(1000, '\n'); // New code
system("pause");
}
Will also require a single input if you enter I the newline will be the discarded character, if you enter I AM TRY then AM TRY and the newline will be discarded
int main()
{
std::string s;
cin >> s;
std::cin.ignore(1000, '\n'); // New code
std::cin.ignore(1000, '\n'); // requires second input
system("pause");
}
Will require two inputs because at the second cin.ignore call, there is an empty cin stram.

How to Differentiate Number 10 from '\n' in a Loop-Continuation Condition?

I have the following portion of code:
cout << "Enter a series of integers: ";
cin >> integer;
while (integer != '\n')
{
cout << ...
cin >> integer;
} // end while
If the user enters 10, my loop is breaking because number 10 = '\n' value in decimal.
How can I get around this issue?
Thanks,
Your attempted code does not work because the operation cin >> integer extracts digits and converts them to an int. It cannot distinguish where the end of the line was.
Instead you should read a complete line, and then extract integers out of that line, e.g.:
std::string s;
std::getline(std::cin, s);
std::istringstream iss(s);
int integer;
while ( iss >> integer )
{
// do something with integer
}
Consider reading the user's input into a std::string first.
If it's not the newline, convert to an int and do your work.
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int main(){
std::string integer;
cout << "Enter a series of integers: ";
cin >> integer;
while (integer != "x") //<- can't be whitespace
{
cout << atoi(integer.c_str()) << std::endl;
cin >> integer;
}
}
By default, input streams will skip any whitespace, including newlines. In other words, you will never have a ten in the input value unless someone entered "10". The general way to handle input is to read until reading fails (e.g. due to EOF):
while(cin >> value)
{
// use value here
}
// failure, EOF or garbage on input
Note that you will have to cin.clear() the stream before reading anything else afterwards, and that you still have the garbage in there that you have to cin.ignore(..). Maybe you want to use line-based input using getline() instead, and then simply check if the resulting string is empty or (try to) parse it as an integer otherwise.
#include <iostream>
int main(void)
{
int integer = 0;
std::cout << "Enter a series of integers: ";
std::cin >> integer;
while (integer != '\n' || integer == 10) {// **this will not work, it's wrong!**
std::cout << integer << std::endl;
std::cin >> integer;
}//end while
return 0;
}

C++ Function Skipping Code

I have written the following code, which compiles fine. However, when I run it, it skips the getline(cin, p[x]); the second time the function is called. Can anyone tell me why?
Here's the code:
#include "stdio.h"
#include "simpio.h"
#include "strlib.h"
#include "iostream.h"
#include "random.h"
int Hp[2], Atk[2], Ddg[2];
std::string p[2];
void player(int x)
{
cout << "Player name: ";
getline(cin, p[x]);
cout << "\tHp: ";
cin >> Hp[x];
cout << "\tAtk: ";
cin >> Atk[x];
cout << "\tDdg: ";
cin >> Ddg[x];
}
main()
{
string go;
player(0);
player(1);
cout << "Go? (Yes/No): ";
cin >> go;
cin.get();
}
I think its because there is still a \n left in the input stream.
Try a cin.ignore() before using getline. I hope it works.
Your cin stream isn't flushed from first use and getline assumes input has been done already. You can flush it using:
cin.clear(); //clear any possible bits
cin.ignore(); //throw away whatever is there left in the stream
The code appears to be "skipping" the second call to std::getline() because the previous call to player() performed an extraction through std::cin that left a newline in the stream. std::getline() only reads characters until the next newline - so what appears to be skipping is just std::getline() failing to input characters because of the residual newline.
The solution is to clear the newline using std::ws:
std::getline(std::cin >> std::ws, p[x]);