I am creating this revese string App but i get a error if i include a space in the string !
#include <iostream>
#include <string>
using namespace std;
int main()
{
int inputa;
cout<<"%%%%%%%%%%%%%%%%%%String Reversing App%%%%%%%%%%%%%%%%%%%%%%%%"<<endl<<endl;
cout<<"\nEnter 1 to continue and 0 to exit"<<endl<<endl;
cin>>inputa;
if(inputa!=0)
{
do
{
string a,c="";
cout<<"\nEnter the string you want to Reverse : ";
cin>>a;
for(int x=a.length()-1; x>=0; x--)
{
c=c+a.substr(x,1);
}
cout<<"\nThe Reverse String is : "<<c<<endl;
cout<<"\nEnter 1 to continue and 0 to exit"<<endl<<endl;
cin>>inputa;
}
while(inputa!=0);
}
//not my home work
}
If I type the following string like "abc def" there i get an error . But otherwise it works perfectly ! Is there some mistake with the codes ! I am new to CPP so it would be helpful if you could help me !
operator>> will stop reading at the first space (as David pointed out) - use getline instead
std::string a;
getline(std::cin, a);
Full edit of your code
#include <iostream>
#include <string>
#include <limits>
int main()
{
std::cout << "%%%%%%%%%%%%%%%%%%String Reversing App%%%%%%%%%%%%%%%%%%%%%%%%\n\n";
std::cout << "\nEnter 1 to continue and 0 to exit" << std::endl;
int inputa;
std::cin >> inputa;
if(std::cin && inputa!=0)
{
std::cin.ignore(std::numeric_limits<int>::max( ), '\n');
do
{
std::string a,c;
std::cout<<"\nEnter the string you want to Reverse : ";
getline(std::cin, a);
for(int x=a.length()-1; x>=0; --x)
{
c+=a[x];
}
std::cout<<"\nThe Reverse String is : " << c << std::endl;
std::cout << "\nEnter 1 to continue and 0 to exit" << std::endl << std::endl;
std::cin >> inputa;
std::cin.ignore(std::numeric_limits<int>::max( ), '\n');
}
while(std::cin && inputa!=0);
}
}
Including David's verbatim answer because he answered with much more detail (David Rodríguez - dribeas) - please +1 him before he deletes it. His answer adds much more information that I did not mention so we are merging this into a single reply at Davids request,
The answer by Adrian is correct, deals with the immediate issue and provides a solution. As to why it enters an infinite loop, the reason is that after reading the first word, you are trying to read an integer std::cin >> inputa, which will fail as cde cannot be parsed as an integer. At this point the stream enters a fail state and subsequent reads will fail without doing anything (until you clear the error state).
What should you do?
If you want to process whole lines, then you should use std::getline, rather than operator>>. Beware on mixing both, as operator>> won't consume the spaces after the read (including new lines) and you might just read an empty line with the next std::getline. You can either always read with std::getline and then parse the line, or use ignore to clear up to the newline. Finally, whenever you perform IO operations, don't expect the operation to succeed: check the state of the stream. If you don't and your loop depends on IO to complete, it is quite easy to enter this sort of infinite loop, where the stream is marked as failed, no later reads succeed and you never break out of the loop.
Related
I thought I understood handling bad input with cin.clear() and cin.ignore(), like it is explained here, but in the following example
#include <iostream>
#include <limits>
using namespace std; //I know that this isn't good practice.
int main () {
int a, b;
while (cout << "Input some int: " && !(cin >> a)) {
cout << "Wrong datatype!\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
while (cout << "Input some int: " && !(cin >> b)) {
cout << "Wrong datatype!\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
if (a > 1) cout << "Some event.\n";
if (b > 1) cout << "Some other event.\n";
return 0;
}
the behavior I want is only present when the unwanted input is some character.
So if I enter x and y, I will again be asked for two ints and get the appropriate outputs, same if I enter a char and an int two times.
However: If I input, say, 2.3, I will get
Input some int: Wrong datatype!
but won't have a chance to correct my input, since the result invariantly outputs "Some event." The second prompt just accepts the float right away.
What's happening, actually, is the 2 in 2.3 is being accepted by the first prompt, leaving .3 in the input buffer. The Wrong datatype! you are seeing is from your second prompt, seeing a ., which is not a valid character for an integer. You then, I assume, enter an integer which is accepted by your second prompt.
This fundamental approach is fragile, and error-prone.
Your obvious intent is to accept a line of input, and process it. If so, then the correct function to do that is std::getline(). That's what its purpose is. That's exactly what it does. The >> operator does not do that. That's not what it's for. Of course, by using the various auxiliary methods, like ignore(), and clear(), one can still achieve that goal, but, as you've discovered, using those functions correctly is not intuitive. Of course, you can spend copious time pouring over their documentation to understand their every semantic behavior, but why bother, when you can simply use std::getline(), and then move on to something else. It's simply easier to do that.
Of course, once a line of input is received, you would like to parse it into an integer. Now is the correct time to use >> to parse it:
std::string line;
if (std::getline(line, std::cin))
{
std::istringstream i{line};
int n;
if (i >> n)
{
// Input parsed
}
}
Isn't this simpler, more straightforward, and less of a gotcha?. Of course, entering "2.3" here will result in the >> operator parsing the "2", and succeeding, leaving ".3" unparsed. If you would like to detect this situation, simply use get() to see what's left in the std::istringstream. Perhaps accept any trailing whitespace, if you wish.
The problem here is when you enter something like 2.3 to a int cin is okay with that. It reads the 2, sees the . so it stops reading and stores the 2 in the variable and leaves the .3 in the buffer for the next call. So, you pass the first loop, get to the second loop, and then you fail as it tries to read in the . into b. Then you clear the .3 and you can enter another input. If you enter another 2.3 the same thing will happen and b will get 2 and the program continues on.
The "bullet proof" way to read in input is to read it in as a std::string and then parse that to make sure the full input was good. That would look like
std::string line;
while (cout << "Input some int: " && std::getline(cin, line)) {
std::stringstream ss(line);
ss >> a;
if (ss.eof()) // we did consume all the input
break;
else
cout << "Wrong datatype!\n";
}
while (cout << "Input some int: " && std::getline(cin, line)) {
std::stringstream ss(line);
ss >> b;
if (ss.eof()) // we did consume all the input
break;
else
cout << "Wrong datatype!\n";
}
When you input "2.3", cin will stop at '.', and interpret '2' as the desired input.
Then, you will clear cin, when the '.' is encountered, discarding 3.
If you then input a new integer, it will accept it.
Many answers here suggest the use of std::getline and string parsing, either using the string functions or stringstreams. This is quite inefficient and not the way the streams are supposed to be used.
Instead, parse the data when it is still in the input stream:
#include <iostream>
#include <cctype>
#include <limits>
struct read_int {
int& a;
read_int(int& aa) : a{ aa } { }
friend std::istream& operator >>(std::istream& is, read_int& ri) {
char delim;
while(!(is >> ri.a) || (delim = is.get(), delim != '\n' && !std::isspace(delim))) {
std::cerr << "Bad!\n";
is.clear();
is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
return is;
}
};
int main() {
int a, b;
std::cin >> read_int(a) >> read_int(b);
std::cout << a << ' ' << b;
return 0;
}
This function will accept input like "4 5" or "4\n6" alike, but requests a new input for data like "4.2", discarding everything read before.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int num;
cin >> num;
string s;
getline(cin, s);
cout << s << " " << num << endl;
return 0;
}
In this code if I input 3 and press enter, then s takes an empty string.
1) If it is taking the first character as a newline, then is there a possible solution of taking line as input after taking an integer as input?
2) If my input is 4567artyu then how it is deciding whether 7 has to go into the s or num ?
I recommend that you always read complete lines of input from your users. It will cause the least confusion.
Ask for input.
Use std::getline to read a line of input.
If you don't want a string but, say, an integer, use std::stoi or (more general) boost::lexical_cast to safely convert the input to your desired target type. This is where you catch poor inputs and complain at the user.
I don't think that many users, if prompted for a number, would expect that entering 42bananas would be accepted as 42 and the bananas part be “remembered” for later. It will most likely be a typo and the user will be happy to be asked to correct it.
For taking line as input after taking integer as input you can consider removing the stray '\n' character from the stream.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int num;
cin >> num;
getchar();
string s;
getline(cin, s);
cout << s << " " << num << endl;
return 0;
}
This will do the trick.
For second question, it reads 4567 as integer, it will continue to read it as integer until limit of int is reached and if limit is reached it will not consider anything after that. Then it will put the maximum value of int in the variable num and null int the string s. If limit is not reached, then string will remain in the input stream as it is, and will be fetched by variable s.
Try using cin.clear before you accept string
I began programming on C++ some days ago and something is really getting me troubles:
whenever I enter the number, the program ends.
Code:
using namespace std;
int main()
{
int entry;
cout << "Write a number: ";
cin >> entry;
cout << entry;
cin.get();
return 0;
}
I need some help here so my programs could run right.
By right I mean to output the number after ending... but it just ends after I enter the number and press enter It does not print it.
UPDATE:
For the sake of the ones who didn't understood what I was meaning (sorry for my english)
Ok let me explain.
-So the program is suposed to get the values from the keyboard right.
-I enter a number let´s say is 6, ok now I press enter.
-Alright now the number is supposed to be output on the screen, but this doesn´t happen because the program closes too fast.
But this was solved actually, by adding a second cin.get(); or by adding a cin.ignore(); after each data input petition.
Here's a slightly improved version that might be closer to what you wanted:
#include <string>
#include <sstream>
#include <iostream>
int main()
{
int n;
std::string line;
while (true)
{
std::cout << "Please enter an integer: ";
if (!(std::getline(std::cin, line))) { return 1; /* error! */ }
std::istringstream iss(line);
if (iss >> n) { break; }
}
std::cout << "Thank you. You said: " << n
<< "\n\nPlease press Enter to quit.";
std::getline(std::cin, line);
}
The error condition in the getline is triggered when the input stream is closed or otherwise terminated before another line could be read (e.g. if you hit Ctrl-D on the console). The token extraction into n fails until you enter a valid integer, and the loop will continue looping until this happens.
All you need to do is consume the newline that is left over after reading the integer.
This happens in java as well.
using namespace std;
int main()
{
int entry;
cout << "Write a number: ";
cin >> entry;
cout << entry;
cin.get(); //Consume newline
cin.get();
return 0;
}
get() reads one and only one character from the stream, so it's perfectly normal that the program ends after you enter your number.
Have a look either at the std::basic_istream<>::getline() method or, easier, std::getline() which doesn't require a dynamic buffer.
If you need more information about basic IO in C++, you can read the following documentation : Basic Input/Output - C++
Update
Like stated in the comments, I missunderstood the question, I was initially thinking that only one digit was read into the variable.
After reading carefully again, I'm unable to understand what the problem is.
The reason for this is youre using
cin.get();
return 0;
at the end of the program , the cin.get() reads the number you entered then goes straight to return 0; thus ending the program.
to stop this you can add an extra cin.get(); before return 0;
or use
system("Pause");
before return 0; instead
Sorry for the noobish question here, but I am just learning C++ and I am looking for the standard way of dealing with this problem. I am using VS2005.
Given a program:
#include <iostream>
using namespace std;
int main( )
{
while ( true )
{
cout << "enter anything but an integer and watch me loop." << endl;
int i;
cin >> i;
}
return 0;
}
If you enter anything but an integer the program will never allow you to enter anything again. Now, I realize that this is because there is input left on the stream after the format fails, so each call to cin << i just reads up to the next end line (I think). How do you guys clear out the stream or deal with this problem? It must be pretty common.
surround the cin call with an if.
The cin will return false if wrong data is read.
so:
if (!cin >> i) {
cin.clear();
cin.ignore(INT_MAX, '\n');
cout << "Haha, your looping efforts have been thwarted dear sir\n";
}
cin.flush() should do the trick (according to cppreference.com) but not on VS apparently.
cin.clear() resets all flags to a good state.
cin.ignore with a large number and until '\n' should work.
Alright, I found the answer. The answer is...
Don't do this. Do not mix formatted and unformatted input using operator >>. Here is a good article on the subject:
http://www.cplusplus.com/forum/articles/6046/
Basically, the code changes to:
#include <iostream>
#include <string>
#include <stream>
using namespace std;
int main( )
{
while ( true )
{
cout << "enter anything but an integer and watch me loop." << endl;
string input;
getline( cin, input );
int i;
stringstream stream( input );
if ( stream >> i ) break;
}
return 0;
}
cin.ignore(int num_bytes_to_ignore); will do it.
You can also use stdio, fflush(fd); where fd is one of stdout,stderr,stdin.
I'd like to know how to limit an input value to signed decimals using std::cin.
double i;
//Reading the value
cin >> i;
//Numeric input validation
if(!cin.eof())
{
peeked = cin.peek();
if(peeked == 10 && cin.good())
{
//Good!
count << "i is a decimal";
}
else
{
count << "i is not a decimal";
cin.clear();
cin >> discard;
}
}
This also gives an error message with the input -1a2.0 avoiding the assignation of just -1 to i.
If the backing variable of the cin is a number, and the string provided is not a number, the return value is false, so you need a loop:
int someVal;
while(!(cin >> someVal)) {
cin.reset();
cout << "Invalid value, try again.";
}
Combining the techniques from the top answer here and this website, I get
input.h
#include <ios> // Provides ios_base::failure
#include <iostream> // Provides cin
template <typename T>
T getValidatedInput()
{
// Get input of type T
T result;
cin >> result;
// Check if the failbit has been set, meaning the beginning of the input
// was not type T. Also make sure the result is the only thing in the input
// stream, otherwise things like 2b would be a valid int.
if (cin.fail() || cin.get() != '\n')
{
// Set the error state flag back to goodbit. If you need to get the input
// again (e.g. this is in a while loop), this is essential. Otherwise, the
// failbit will stay set.
cin.clear();
// Clear the input stream using and empty while loop.
while (cin.get() != '\n')
;
// Throw an exception. Allows the caller to handle it any way you see fit
// (exit, ask for input again, etc.)
throw ios_base::failure("Invalid input.");
}
return result;
}
Usage
inputtest.cpp
#include <cstdlib> // Provides EXIT_SUCCESS
#include <iostream> // Provides cout, cerr, endl
#include "input.h" // Provides getValidatedInput<T>()
int main()
{
using namespace std;
int input;
while (true)
{
cout << "Enter an integer: ";
try
{
input = getValidatedInput<int>();
}
catch (exception e)
{
cerr << e.what() << endl;
continue;
}
break;
}
cout << "You entered: " << input << endl;
return EXIT_SUCCESS;
}
Sample run
Enter an integer: a
Invalid input.
Enter an integer: 2b
Invalid input.
Enter an integer: 3
You entered: 3.
cin's >> operator works by reading one character at a time until it hits whitespace. That will slurp the whole string -1a2.0, which is obviously not a number so the operation fails. It looks like you actually have three fields there, -1, a, and 2.0. If you separate the data by whitespace, cin will be able to read each one without problem. Just remember to read a char for the second field.
I tried many techniques for reading integer input from the user using the >> operator, but in a way or another all my experiments have failed.
Now I think that getline() function (not the method with the same name on std::istream) and the strtol() function from the include cstdlib is the only predictable consistent solution for this problem. I would appreciate if someone proved me wrong. Here is something like the one I use:
#include <iostream>
#include <cstdlib>
// #arg prompt The question to ask. Will be used again on failure.
int GetInt(const char* prompt = "? ")
{
using namespace std; // *1
while(true)
{
cout << prompt;
string s;
getline(cin,s);
char *endp = 0;
int ret = strtol(s.c_str(),&endp,10);
if(endp!=s.c_str() && !*endp)
return ret;
}
}
*1: Placing using namespace whatever; to the global scope may lead to broken "unity builds" (google!) on larger projects, so should be avoided. Practice to not use that way, even on smaller projects!
Reading integers from files is a very different matter. Raúl Roa's approach can be good for that if properly worked out. I also suggest that wrong input files should not be tolerated, but it really depends on the application.
Be warned that using >> and getline() in the same program on cin will lead to some problems. Use one of them only, or google to know how to handle the issue (not too hard).
Something like:
double a;
cin >> a;
Should read your signed "decimal" fine.
You'll need a loop and some code to make sure it handles invalid input in a sensible way.
Good luck!