C++: how do I check if the cin buffer is empty? - c++

How do you check to see if the user didn't input anything at a cin command and simply pressed enter?

When reading from std::cin, it's preferable not to use the stream extraction operator >> as this can have all sorts of nasty side effects. For example, if you have this code:
std::string name;
std::cin >> name;
And I enter John Doe, then the line to read from cin will just hold the value John, leaving Doe behind to be read by some future read operation. Similarly, if I were to write:
int myInteger;
std::cin >> myInteger;
And I then type in John Doe, then cin will enter an error state and will refuse to do any future read operations until you explicitly clear its error state and flush the characters that caused the error.
A better way to do user input is to use std::getline to read characters from the keyboard until the user hits enter. For example:
std::string name;
getline(std::cin, name); // getline doesn't need the std:: prefix here because C++ has ADL.
ADL stands for argument-dependent lookup. Now, if I enter John Doe, the value of name will be John Doe and there won't be any data left around in cin. Moreover, this also lets you test if the user just hit enter:
std::string name;
getline(std::cin, name);
if (name.empty()) {
/* ... nothing entered ... */
}
The drawback of using this approach is that if you want to read in a formatted data line, an int or a double you'll have to parse the representation out of the string. I personally think this is worth it because it gives you a more fine-grained control of what to do if the user enters something invalid and "guards" cin from ever entering a fail state.
I teach a C++ programming course, and have some lecture notes about the streams library that goes into a fair amount of detail about how to read formatted data from cin in a safe way (mostly at the end of the chapter). I'm not sure how useful you'll find this, but in case it's helpful I thought I'd post the link.
Hope this helps!

cin will not continue with the program unless the user enters at least 1 character (enter doesn't count). If the user doesn't give ANY input, cin will just keep waiting for the user to give input and then press enter.

The Simple way >>
{
char X=0; // ASCII( 0 ) means a NULL value
cin>>X;
if(X==0 || X==10) // ASCII( 10 ) means ENTER
cout<<"User din't enter ANYTHING !! ";
}
But a simple problem is....
cin just won't allow you to move further without entering a character
by character here i mean a DIGIT or alphabet or special symbol , not space, enter null etc
Hope this solves your problem, if it doesn't, I'll be glad to help just let me know.

int main(){
string str[100];
std::cout<<"Hello how are you ? \n";
std::cin>>str;
if(str.length() > 0){
// If input is seen
}
else{
// If input is not seen
}
}
Any problem let me know.

Related

How do I get a variable amount of input from cin?

I've been working on a calculator and I am very close to getting it working, but I need to find a way to have the amount of numbers and operators that the user puts in to be up to the user. This is a simpler test version of what I have so far that I need to apply this to. I left out a few things but this is the exact part of the code I need to apply it to. The user should be able to input any amount of numbers and operands as long as it is under 20 of each. I don't want to stick to a rigid form of input, like cin >> numIn[n]; cin >> operator1[n], because then you would HAVE to end with an operator, for example.
#include <iostream>
float numIn[20];
char operator1[20];
int main(){
int n = 0;
while (n < 20){
std::cin >> numIn[n] >> operator1[n];
switch (operator1[n]){
case '+':
std::cout << numIn[n] + numIn[n];
break;
default:
std::cout << "does not work";
}
}
}
I edited this question to be more focused and clear. I added the part of the text above about how I need to have a 'fluid' way of input. If this doesn't make it more clear I don't know what does.
Use getline to get a whole line of input from the user.
Then use that string to construct a stringstream, which you can use your >> on to extract the numbers and single-char operators. But now you get an error when you try to read past the end of the original string. It knows you are done, because it has the complete input committed before it started to read, unlike an always-open terminal where the user could always type more.
use std::cin >> numIn[n] and std::cin >> operator1 [n]
as #Ivan suggested in the replies

Pause Function it is Looping Forever

I am trying to implement a pause function in C++, but it is looping forever.
I am using macOS but I am trying to create a pause function that will work in any system... I believe my cin >> is not capturing '\n' or '\r' from the keyboard and it is looping forever.
void Transferencia::pause() {
char enter = 0;
while(enter != '\n' && enter != '\r') {
cout << "(Press Enter to Continue...) ";
cin >> enter;
}
cin.clear();
}
I want to pause my program until user press the key "enter".
But even when I press "enter/return" it keeps looping...
At very first: enter != '\n' || enter != '\r' is a tautology: Even if enter does equal one of the characters it cannot be equal to the other one. So one of the tests must be true... You actually want to stay in the loop when enter is unequal to both values.
std::cin >> ... won't read data before you press enter, but it will discard the newlines (actually, all whitespace). So it would suffice just to read one single character right without loop (the loop again would get an endless one); solely: If the user doesn't enter anything at all before pressing 'enter' key, there's no character to read from std::cin and we'd still be waiting.
What you can do is reading entire lines:
std::string s;
std::getline(std::cin, s);
That will accept empty lines as well, so does exactly what you want (note: no loop around!).
Edit (stolen from the comments; thanks, Thomas Matthews): An even more elegant way is
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
as it won't create any additional resources that would be discarded afterwards anyway (the std::string object!).
Edit 2:
Depending on type of last input operation, there might still be a newline (or even further data) buffered, e. g. after int n; std::cin >> n;. In this case, you need to skip the input yet buffered. So you would need ignore twice.
However, if the last input operation consumed the newline already (e. g. std::getline – or if there wasn't any preceding input operation at all), then this would lead to user having to press enter twice. So you need to detect what's has been going on before.
std::cin.rdbuf().in_avail() allows you to detect how many characters are yet buffered. So you can have:
if(std::cin.rdbuf().in_avail())
{
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
std::cout << "press enter" << std::endl;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
On some systems (including mine), though, in_avail can return 0 even though a newline is yet buffered! std::cin.sync_with_stdio(false); can fix the issue; you should execute it before very first input operation. Hopefully, you don't use C++ (streams) and C (scanf, printf, etc) IO intermixed then...
The easiest way to do this is with getline().
cin >> ignores whitespace, newline characters included. getline() will read an entire line, newline character included. However, it does not copy the newline character to the output string. If the user simply hit the enter key and nothing else, you'd end up with an empty string.
So, to get your desired behavior, you would construct your loop like this:
string line;
while(true)
{
cout << "(Press Enter to Continue...) " << endl;
getline(cin, line);
if(line == "")
break;
}
#Aconcagua has answered your question but this is what I want to add in.
Normally, for handling some specific kind of event in computer, we usually follow event-driven paradigm or event-callback.
The idea is there is an event loop that waits for a new event coming into the system. This case, keyboard is an event, the event loop then calls event-callback. What event-callback does is it compares the value of input with some conditions then do some other tasks (it might change some state of the program or notify users).
The idea is keep CPU busy by either 2 ways.
event-driven : do other tasks while waiting for a new event
multithreading: multiple threads in the system. This approach has the disadvantage is at data-race
Have fun

Can someone explain to me how this code works?(Program to ask for user input again if a numeric value expected and the user enters some other input)

I was reading a book on c++ (c++ primer plus) and found this code.
The purpose of the program is that if a numeric input is expected from the user to read it to ,say an array->
1)Reset cin to new input
2)Get rid of the bad input
3)Prompt the user to try again (exact words of the book)
Here is the code->(exact code copied from the book)
#include <iostream>
const int Max=5;
int main()
{
using namespace std;
//get data
int golf[Max];
cout<<"please enter your golf scores.\n";
cout<<"you must enter "<<Max<<" rounds.\n";
int i;
for(i=0;i<Max;i++) {
cout<<"round #"<<i+1<<": ";
while(!(cin>>golf[i])) {
cin.clear();
while(cin.get()!='\n')
continue;
cout<<"PLease enter a number: ";
}
}
double total=0.0;
for(i=0;i<Max;i++)
total+=golf[i];
cout<<total/Max<<" = average score "<<Max<<" rounds\n";
return 0;
}
The particular part which i don't understand is:
cin.clear();
while(cin.get()!='\n')
continue;
I'm a little unclear about the function of cin.clear() , the need of continue here , and what the while test conidtion does and how does it work.
A test run->
(italic part is the user input)
Please enter your golf scores.
You must enter 5 rounds.
round #1: 88
round #2: 87
round #3: duh
Please enter a number: 103
round #4: 94
round #5: 86
91.6 = average score 5 rounds
while(!(cin>>golf[i]))
{
cin.clear();
while(cin.get()!='\n')
continue;
cout<<"PLease enter a number: ";
}
First let's example the while condition. It seems to check if the value of the expression (cin >> golf[i]) is false. The falue of cin >> golf[i] is cin itself. So how can it be false? If a >> operation fails for the input stream, a flag named fail is set. That's what operator ! checks. So the condition means while after trying to read a number the object cin has fail set, do...
Now, once the fail flag is set, there isn't much you can do with an input stream. You won't be able to continue reading data from the stream unless you reset the fail flag. That's what cin.clear() does.
Then it munches the rest of the bad input line (which was NOT consumed since >> failed) by reading character by character until reaching the end of line.
And finally it prompts the user for new input.
Since golf[i] is an int, cin>>golf[i] will return true (or a value interpreted as true in earlier versions of C++ Standard Library) when the input is an int. Hence, while(!(cin>>golf[i])) will repeat until true is returned.
Inside the while loop you find code that ignores all input until a \n with the loop that stops only after receiving '\n' input:
while(cin.get()!='\n')
continue;
It also clears the flag indicating that cin is in a failure state by calling clear().
Note: This code makes an assumption that cin never ends, which makes it unsafe. If the input is taken from a file with invalid data, this program will be stuck in an infinite loop.

C++ cout print twice in do while loop

The system did this:
Please input the Full Name of the user:Please input the Full Name of the user:
It output the string "Please input the Full Name of the user:" twice , how do i change the code to make it just cout once
string fullname = "";
do
{
cout << "Please input the Full Name of the user: ";
getline (cin,fullname);
}while(fullname.length()<1);
C++ What is causing the system to output twice
You could try flushing your input stream to get rid of leftover newlines:
std::cin.ignore(x);
(with x being the number of characters to ignore, e.g. INT_MAX).
Simple solution would be to move the std::cout statement outside of the do-while loop.
string fullname = "";
cout << "Please input the Full Name of the user: ";
do
{
getline (cin,fullname);
}while(fullname.length()<1);
You are performing an input operation without checking the result, which is a hard programming and understanding error. Do this instead:
for (std::string line; ; )
{
std::cout << "Name: ";
if (!std::getline(std::cin, line) || !line.empty()) { break; }
}
The first condition checks whether the input succeeded (which is false when the input stream is closed), and the second checks whether the read line is non-empty. The short-circuit semantics of || make the second check legal.
As others have pointed out the problem is that you have an extra '\n' character on the input stream.
Contrary to the popular answer I don't think flushing (ignore()) the current input is a good solution. You are treating the symptom not the problem. If you are using ignore() you are potentially throwing away user input that you might actually want or something that could have detected an error from the user:
> Input Your age
> 36xxxx
// If you use
std::cin >> age;
// Then sometime later in your code you use
// ignore to make sure that you have "correctly" skipped to the next new line
std::ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// You have now just ignored the fact that the user typed xxx on the end of the input.
// They were probably doing that to force an error in the code or something else erroneous
// happened but you just missed it with std::ignore()
The best solution is not to get into this situation.
This problem is caused by using a combination of operator<<() and std::getline() to parse user input. I love using operator<<() to parse normal or regular input; but manual user input (ie Question/Answer) is harder to predict and users input is line based (there input ends at the '\n' character because the buffer is flushed when they hit <enter>).
As a result when I parse manual user input I always use std::getline(). This way I know I got the whole of their answer. It also allows me to validate the input to make sure there was not a typing error.
std::cout << "What is your age\n";
std::string line;
std::getline(std::cin, line); // Get user input
// Use stream for easy parsing.
std::stringstream linestream(line);
// Get value we want.
linestream >> age;
// Validate that we have not thrown away user input.
std::string error;
linestream >> error;
if (error.length() != 0) { /* do stuff to force user to re-input value */ }

cin.get in a while loop

I'm trying to get input from user and give output until s/he presses 'n'. It doesn't seem to work. Is problem in scanf or cin.get? When I press y it just takes "tekrar" as an input, thus gives "y" as output and goes into a loop. Also, doesn't stop when i give n as tekrar input.
char cevap[300]="";
char tekrar='y';
while (tekrar!='n')
{
cin.get(cevap,300);
cout<<cevap<<endl;
cout<<"Again? (y/n)";
scanf("%c",&tekrar);
}
output:
Hello
Again? (y/n)
y
Again? (y/n)
y
Again? (y/n)
n
Again? (y/n)
n
...
Mixing the various input methods on istream (get, getline, operator>>) can be fraught with peril if you're not aware of which methods leave the delimiter character in the stream and which don't, and handle them accordingly.
In this case, get will read 300 characters of input or input up until the newline, whichever happens first. The newline will not be extracted, and so will remain in the stream. That means your call to scanf() will read the newline and stop, leaving the y or n you just typed in the stream.
There are several ways to reorganize this code to make it do what it seems like you want. This is one way:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string cevap;
char tekrar='y';
while (tekrar!='n')
{
getline(cin,cevap);
cout<<cevap<<endl;
cout<<"Again? (y/n)";
tekrar = cin.get();
cin.ignore();
}
return 0;
}
This uses std::string and the non-member getline to read input in such a way as to not require you to be limited to 300 characters (not strictly speaking related to the question, but good practice usually). getline consumes and discards the delimiter, but get, used to read the continuation input, doesn't, so we discard it manually via ignore.
Use cin operator>> to read from stdin, instead of scanf:
string cevap;
char tekrar='y';
while (tekrar!='n')
{
getline(cin, cevap);
cout<<cevap<<endl;
cout<<"Again? (y/n)";
cin >> tekrar;
cin.get();
}
Edit: fixed the infinite loop. You should use std::string instead of a simple char array.