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";
Related
void Manager::ManagerView1()
{
system("cls");
string Ipass;
string Opass;
ifstream Password("Password.txt", ios::in);
if (!Password)
{
cerr << "Check File Integrity";
}
else
{
while (!Password.eof())
{
getline(Password,Ipass);
cout << "Enter Password :\n";
cin >> Opass;
if (Opass == Ipass)
{
cout << "Passwords Match";
}
}
}
}
Text inside the "Password.txt":
Abhik Ray 1123
The password is being read properly, I have already checked that.
When I run the code it lets me enter the password but then the Passwords match doesn't show up as it should. And then it again asks for the password where I am unable to enter it. And then it just quits.
What should I change?
You have several problems, like trying to match only one line from the password file at a time.
The reason for the message is that if (Opass == Ipass) compares the addresses of the character arrays, not their contents.
If you had used std::string to store the strings, the comparison would have worked, but with C style strings you need to use if(strcmp(Opass, Ipass) == 0).
You might also want to check this question for how to terminate the loop:
Why is iostream::eof inside a loop condition considered wrong?
In the new version of the code with cin >> Opass; the >> will only read one word at a time (it stops at each space). So if you type Abhik Ray 1123 you will only get Abhik in Opass, and the rest of the line will remain in the input buffer until the next read.
That's also why it doesn't ask for the next input, it just reads the following words that are already there.
To read a whole line of input, you need to use getline(cin, Opass);, just like when you read from the textfile.
Opass and Ipass are pointers and by doing Opass == Ipass you check if they point to the same area in the memory.
You have to use strcmp to compare their values.
I need to read lines from standard input, but I dont really know, how many it will be.
I tried to do it with getline() and cin combined with a while loop, but it led to an infinite loop:
string line;
while( getline(cin, string) ){...}
or
string word;
while( cin >> word ){...}
it doesnt stops at the end of the input( the lines are coming at one time, so the user is hitting just one time the Enter key ).
Thanks for your help.
Reading your comments you have a misunderstanding of "end of input".
When you start your program it waits for input from console, and if input is available it reads it. Initially your copy some strings to your console so your program takes this as input. But your program still keeps reading from the console because there was no "end of input". The program is still connected to the console.
You need to signal "end of input" to your program. On Windows you do this by pressing Ctrl+Z. On Linux you need to press Ctrl+D.
Your problem is reading from the console.
As your console does not put an EOF(end of file) when you enter an empty line.
You should try pipeing the input from a file to your program. This should end, when there is no more input.
Otherwise, just check if the string is empty, and break out of the loop, if it is empty.
The way you run your program, your input doesn't end, since the console can always provide more input. Your program behaves correctly, though perhaps not in the way you desire. That's because you have misunderstood your own desires.
What you are looking for is perhaps (but I can't be sure) for the program to end when either the input ends or when the input contains a blank line. This can be coded as follows:
int main()
{
for (std::string line; std::getline(std::cin, line); )
{
if (line.empty())
{
std::cout << "Got blank line, quitting.\n";
return 0;
}
// process line
}
std::cout << "End of input, quitting.\n";
return 0;
}
I'm starting with C++ in college (before used Modula2). I have problems with cin.
While interacting with the user, I need to recognize certain "commands".,
For example "addClient Rafael". I handle it the following way
cin >> command, strcoll (command, "addClient"), and then, if command equals addClient, y do
cin >> command2 (so I read Rafael),. and do the proper procedures...
But also, I have to recognize "deleteAll" which deletes all my database, so I dont have to read the second parameter.
When someone enters random things such as "skjdsjfnsdj" its supossed to say "Wrong command" for which, if command didnt equal none of my "known" commands it printf "wrong command".
The problem is, when some types "skajskajs jakasjkajs" it says "wrong command. worng command"... it should only say it once...
So, "noskip" i thing is no use, maybe if i could break the string.., maybe a simpler way, help anyone?
The most flexible and intuitive way to do this is as follows:
bool done = false;
while( !done ) {
string commandLine, cmd, value;
getline( cin, commandLine );
istringstream ss(commandLine);
ss >> cmd >> value;
if( cmd == "deleteAll" ) {
// BOOM
}
else if( cmd == "addClient" ) {
// Do something with 'value'. You could wait until here to read it
// if you want, instead of always attempting to read it.
}
else if( cmd == "quit" ) {
done = true;
}
else {
cout << "Wrong command\n";
}
}
Or edit to suit your purposes. I use this sort of approach for parsing simple key/value pair config files. Works a treat, and takes almost no effort to code.
You could simply try istream::getline() instead.
It will prevent the message appearing more than once for each command (separated by a \n).
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 */ }
I'm a bit confused by the results of the following function:
int main() {
string command;
while(1) {
cin >> command;
if(command == "end")
return 0;
else
cout << "Could you repeat the command?" << endl;
}
return 0;
}
First of all - the output line ("could you...") repeats once for each individual word in the input (stored in command). So far as I can see, it should only be possible for it to happen once for each instance of the loop.
Also, when the line 'if(command == "end")' is changed to 'if(command == "that's all")' it never triggers. A little testing suggested that all of the whitespace was removed from the command.
Could someone explain to me what's going on here?
Thanks
The formatted input operator >>() reads space separated tokens from input. If you want to read whole lines, use the getline() function:
string command;
getline( cin, command );
Most (possibly all) operating systems buffer input. When you type a string of words and then hit [enter] it is only at the time you hit enter that the input is usually passed to your program. Thus that is when it will start reading the input and separating it out into individual words (because as Neil mentions, the >> reads words, not lines). Thus your program goes through the loop multiple times (once per word you had in the line) even though you only hit enter once.
So, you are correct when you think it should only display "could you..." once per loop. That is what is happening.
Likewise, you'll never have a command that contains more than one word because of the space delimiter. As mentioned, use getline() to retrieve the entire text for the line you entered.