C++ cout print twice in do while loop - c++

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 */ }

Related

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

How while(!(cin >> x)) works to re-prompt for input

while(!(cin >> ar[i]))
{
cin.clear(); // clears bad input
while(cin.get() != '\n')
continue;
cout << "Invalid input, please enter valid scores";
}
The above code is from a much larger file. I copied this bit of a code from one of my textbooks and I don't really feel comfortable using it as I do not understand how this works.
I am using it as a measure to handle input errors.
So ar is an empty array of integers, if I decide to enter 'k', then
!(cin >> ar[i])
is true.
From here I clear the input buffer (I think that is correct, I'd like someone to confirm or dispute this please). The terminal then prints "Invalid input..."
Now if I just press Enter nothing happens, but isn't Enter the newline char? So shouldn't the code read
while(cin.get() == '\n'
?
while(!(cin >> ar[i]))
This tries to parse a value from cin and store it in ar[i]. By default, >> skips whitespace first, then sees if the characters in cin describe a legal value for whatever the type of ar[i] is. If a legal value is found, then cin stream state remains good, and its operator bool() const will kick in given the boolean not/! operation, such that the while loop will break.
If parsing fails though, the stream state will be set to one or more of:
bad (if there's some unrecoverable stream error, like stdin supplied over a network connection that gets disconnected),
fail (if the characters just didn't form a legal value for the type), or
eof (end of file, for a "proper" shutdown/close of the input, as supplied by ^D in UNIX/Linux, ^Z in Windows, and the end of input when a program's invoked as in echo input | program).
All the above modalities are described under "State Functions" here.
If the loop is entered due to any of the error conditions above...
{
cin.clear(); // clears bad input
...this does NOT clear any input data from the stream, but does clear the bad, eof and fail state flags, after which further input attempts can be made, though a stream that was in bad or eof state is likely to immediately reenter that state when further input is attempted (but not always - some OS may allow successful input after an eof conditions for std::cin if the user types/generates an EOF code then types actual text again...
while(cin.get() != '\n')
continue;
This tries to read characters from the terminal until a newline \n is encountered. The idea's clearly to clear out the rest of the presumed unparse-able input that might have led to a fail condition earlier. Sadly, if the problem was, or becomes, a bad or eof condition then this loop will hang the program, spinning burning CPU to no avail.
cout << "Invalid input, please enter valid scores";
}
If the problem was simply a mistyped value and no bad or eof condition, then the cout will prompt for further input.
Now if I just press enter nothing happens, but isnt enter the newline char?
Whenever the outer loop is executing cin >> ar[i] it will skip whitespace, including any extra newlines you type, until it sees some input (which may need to be a full newline-terminated line to get flushed by the terminal or program feeding it to the program), or a bad or eof condition. The inner while-loop is not there to get rid of empty lines - it's trying to discard the line with presumed non-numeric text in it.
Corrected code:
while (!(std::cin >> ar[i]))
{
if (std::cin.bad() || std::cin.eof())
{
std::cerr << "Fatal error on cin while reading numbers\n";
exit(EXIT_FAILURE);
}
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Invalid input, please enter valid scores\n: ";
}
The goal of this entire code is to keep printing errors and requesting input until the user enters a valid number before continue further into the program.
The loop that the entire code is enclosed in...
while(!(cin >> ar[i]))
says to loop if the input in the cin stream is invalid. Since ar is an array of integers, the input would be invalid if it is not a number.
cin.clear(); // clears bad input
When the cin stream encounters invalid input, the program begins executing the loop and continues to this line of code. Since the stream encountered invalid input, it has a flag that says there is an error. This requires that you, as the comment puts it, "clear bad input." Basically what this does is get rid of this flag. If this is not done, the flag will remain in the stream and the program will encounter another error next time the cin stream is used, regardless of whether or not the user input is valid.
while(cin.get() != '\n')
continue;
When the program took the input from the user, it took the string, char, whatever was the invalid input, but left the '\n' in the cin stream. To prevent errors the next time the cin stream is used, the program must get rid of that '\n', along with anything else that was lefty behind. cin.get() reads only one char from the cin input stream and returns it. Since the return value of this function is not being assigned to anything, all this does is discard the char that was read. In the case that more than the '\n' was left behind in the stream, this loop checks the value of the read char before disposing of it. This way, the loop keeps executing while the char that is read is NOT '\n'. Or in other words, it loops until the char that is read IS '\n'. The only thing that continue does, is tell the program to skip the rest of the current iteration of the loop and start the next iteration. In this situation, this is equivalent to giving the loop an empty body. You could very well replace continue; with {} and the program would do the exact same thing.
cout << "Invalid input, please enter valid scores";
The program has cleared the flag in cin and has also cleared any data from cin that may have been left behind. Now that all the errors from the invalid input have been handled, there is only one more thing to do. It's time to notify he user that the input was invalid and request new input. If the user enters more invalid input, the loop repeats. If the user enters valid input, the program continues on to the next line of code.

Detect a newline character with getline or istringstream

In my program, I'm asking the user for input via getline, and then in a separate class, splitting the string into three different strings which I will then check via a list of pre-determined values.
The way it works now, if someone enters an invalid command, I display "INVALID"
The problem I'm having is with a string containing only spaces or only a single newline character.
Here is what I'm trying to do:
std::string command; // command user enters
getline(std::cin, command); // user input here
std::string tempCheck; // if we have a value in here other than empty, invalid
// use istringstream to grab the words, max of 3
std::istringstream parse{fullCommand}; // parse command into words
if(fullCommand.empty()){ // nothing has been input
std::cout << "INVALID" << std::endl;
return;
}
parse >> command; // stores first word (the command)
parse >> actionOne; // stores second word as parameter
parse >> actionTwo; // stores third word as parameter
parse >> tempCheck;
if(!tempCheck.empty()) {
std::cout << "INVALID" << std::endl;
return;
}
The variable tempCheck basically means that if it goes over three words (the limit I want for commands), then it is INVALID. I also thought that having an empty string would work, but it just ends up in an infinite loop when nothing is input, but I just hit enter.
Here is what I expect my input to be doing (bold is output):
CREATE username password
**CREATED**
LOGIN username password
**SUCCEEDED**
ASDF lol lol
**INVALID**
**INVALID**
REMOVE username
**REMOVED**
**INVALID**
QUIT
**GOODBYE**
Here is what is happening:
CREATE username password
**CREATED**
// newline entered here
And it goes into a seemingly infinite loop. I can still type things, however, they don't actually affect anything. For example typing QUIT does nothing. But, if I restart my program and just type "QUIT" without trying to only use a newline character or only use a space, I get the expected output:
QUIT
**GOODBYE**
So, how do I tell either getline, or my istringstream, that if a user just enters a bunch of spaces and then hits enter, OR if the user just hits enter, display invalid and return? And is there anyway to do this with just getline or istringstream?
Alex, the following code may be helpful:
std::string strip(std::string const& s, std::string const& white=" \t\n")
{
std::string::size_type const first = s.find_first_not_of(white);
return (first == std::string::npos)
? std::string()
: s.substr(first, s.find_last_not_of(white)-first+1);
}
You may apply it before creating the istringstream:
std::istringstream parse{strip(fullCommand)};
The above code was borrowed and slightly modified from the old well-known technique.

Keep looping until user enters a blank line?

So I've run into the following problem. My goal is to create a loop that keeps taking user input over and over until the user doesn't enter anything into 'cin >>', leaves the line blank, and simply presses the ENTER key to move on, at which point the program is supposed to break out of the loop and continue on with the rest of program execution. Something like this:
do {
cout << "\nEnter a name: ";
cin >> input1;
if (input1.empty())
{
break;
}
else
{
user_name = input1;
}
} while (!input1.empty());
As you can see, I've already tried using the empty() function, but that didn't work, the program simply stays in the loop and doesn't break out, no matter how many times I press enter. It just keeps prompting me to enter a name. I've also tried using something like
if (input1 == "")
but that doesnt work either. Can anyone help? How do I break out of this loop?
UPDATE: OK guys, I've tried your recommendations, and it worked! Thank you so much! Unfortunately, although the getline function works, it has also created a new problem for me. Basically, in the first initial loop, the program prompts for a name, I type in a name, and the name is stored in user_name. However, in the SECOND loop, the program doesn't even give me the chance to enter any input, it simply prints "Enter a name: ", and then instantly exits out of the loop, and continues on with the rest of program execution. Why is this happening?
Use this getline(std::cin, input1):
while (getline(std::cin, input1))
{
if (input1.empty())
break;
username =input1;
std::cout << input1 << std::endl << "Enter Input : ";
}
Use std::getline(cin, input1); instead to read a line from the console.
Using cin directly reads exactly one word from stdin. If the user does not input anything, no word has been given and cin does not return yet (your empty check is not even executed).
After you use std::getline you can leave your empty-check as-is:
std::getline(cin, input1);
if(input1.empty())
break;
BTW: In C++ you should also check if the underlying stream has run into an error. So check the return code of cin or getline. This can be done with the following code:
if(!std::getline(cin, input1))
// I/O error
In general, looping until an empty line is entered would be:
while ( std::getline( line ) && !line.empty() ) ...
If you need a prompt: the prompt is part of the input logic, and
should be implemented as such:
std::string
getlineWithPrompt( std::string const& prompt )
{
std::cout << prompt;
std::string results;
return std::getline( std::cin, results )
? results
: std::string();
}
You then do something like:
std::string line = getlineWithPrompt( "prompt for first line" );
while ( !line.empty() ) {
// ...
getlineWithPrompt( "prompt for further line" );
}
(This is actually somewhat simplified, as it treats hard errors
on input, end of file, and empty lines identical, which is
rarely the right thing in professional software. But for
learning purposes, it should be sufficient.)
Cin won't read the whitespace that you call an empty line. Getline may do this, but I am not entirely sure. You could define an end character that the user would type and check for that. Gets would also work, it will just set the starting character to 0x0. Be careful with gets(), it is prone to allow buffer overflows.
This works as well:
char line[128];
do
{
cout << "Enter something: ";
gets(line);
} while (strcmp(&line[0], "\0") != 0);
#JamesKanze
So something like this to exit the while loop?
string str = "foo";
while (str == "foo"){
getline(cin, str);
}
str = "foo";

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

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.