#include <iostream>
#include <limits>
using namespace std;
int main()
{
int x;
cout << "5 + 4 = ";
while(!(cin >> x)){
cout << "Error, please try again." << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
if (x == (5 + 4)){
cout << "Correct!" << endl;
}
else{
cout << "Wrong!" << endl;
}
return 0;
}
How can I check if the user inputs a valid integer? In this program I wrote above, if the user inputs 9, it should be correct, however, if the user inputs 9a for example, it should return an error, but it doesn't for some reason. How can I correct it?
How I did it using cin.peek()
#include <iostream>
#include <limits>
#include <stdio.h>
using namespace std;
int main()
{
int x;
bool ok;
cout << "5 + 4 = ";
cin >> x;
while(!ok){
cin >> x;
if(!cin.fail() && (cin.peek() == EOF || cin.peek() == '\n')){
ok = true;
}
else{
cout << "Error, please try again." << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
if (x == (5 + 4)){
cout << "Correct!" << endl;
}
else{
cout << "Wrong!" << endl;
}
return 0;
}
You could read a string, extract an integer from it and then make sure there's nothing left:
std::string line;
std::cin >> line;
std::istringstream s(line);
int x;
if (!(s >> x)) {
// Error, not a number
}
char c;
if (s >> c) {
// Error, there was something past the number
}
bool isIntegerNumber(const std::string& string){
std::string::const_iterator it = string.begin();
int minSize = 0;
if(string.size()>0 && (string[0] == '-' || string[0] == '+')){
it++;
minSize++;
}
while (it != string.end() && std::isdigit(*it)) ++it;
return string.size()>minSize && it == string.end();
}
You have a line oriented input, so you should probably be using
getline. Something like:
bool
getIntFromLine( std::istream& source, int& results )
{
std::string line;
std::getline( source, line );
std::istringstream parse( source ? line : "" );
return parse >> results >> std::ws && parse.get() == EOF;
}
should do the trick.
Using this, your loop would be:
while ( !getIntFromLine( std::istream, x ) ) {
std::cout << "Error, please try again." << std::endl;
}
Note that this technique also means that you don't have to worry
about clearing the error or resynchronizing the input.
For the reason this happens, take a look at this link:
Extracts and parses characters sequentially from the stream to
interpret them as the representation of a value of the proper type,
which is stored as the value of val. Internally, the function accesses
the input sequence by first constructing a sentry object (with
noskipws set to false). Then (if good), it calls num_get::get (using
the stream's selected locale) to perform both the extraction and the
parsing operations, adjusting the stream's internal state flags
accordingly. Finally, it destroys the sentry object before returning.
Then observe the behavior if you attempt something like this:
int x = 0;
cin >> x;
std::cout << x << std::endl;
std::cout << cin.good() << std::endl;
g++-4.8 -std=c++11 -O3 -Wall -pedantic -pthread main.cpp && echo "900a100" | ./a.out
// Output:
// 900
// 1
If you input "a100" instead, it outputs:
0
0
try this:
std::string input;
std::cin >> input;
if ( std::all_of(input.begin(), input.end(), std::isdigit) )
{
//input is integer
}
Refer this :
C++ Fix for checking if input is an integer
One I have seen that works for some situations is:
Read the input as string. cin >> str
Decode to number: atoi, or sscanf, or stringstream, etc.
print the number into a string (using sprintf or stringstream)
check if its equal to read string. (using strings ==, not char*)
Quick and simple to do. Uses the Cin>>str word breaking rules, accept negative numbers, rejects overflowing numbers. But it does reject "+10", which in somesituations you are happy wiht, and in some you are not.
If you can use C++11 (and your compiler has full regex support), you can also use the <regex> library:
#include <iostream>
#include <limits>
#include <regex>
#include <string>
#include <utility>
int main()
{
std::string line;
std::pair<int, bool> value = std::make_pair(0, false);
std::cout << "5 + 4 = ";
while (!value.second)
{
while (!std::getline(std::cin, line))
{
std::cout << "Error, please try again." << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
if (!std::regex_match(line, std::regex("(\\+|-)?[[:digit:]]+")))
{
std::cout << "Error, please try again." << std::endl;
}
else
{
value = std::make_pair(std::stol(line), true);
}
}
if (value.first == (5 + 4))
{
std::cout << "Correct!" << std::endl;
}
else
{
std::cout << "Incorrect!" << std::endl;
}
return 0;
}
Related
I want to add the check-in my c++ code that user can not enter not integral values in reg. If he inputs, he is prompted again. I saw the solutions in the stack overflow that was of 2011 (How to check if input is numeric in C++). Is there some modern or good way now or is it same?
I tried using ifdigit() in ctype.h
// Example program
#include <iostream>
#include <ctype.h>
using namespace std;
int main()
{
int x;
cout<<"Type X";
cin>>x;
if(!isdigit(x))
{
cout<<"Type Again";
cin>>x;
}
}
but it didnt worked
here is my actual problem where I want to add check.
cout << "Type Reg # of Student # " << i + 1 << endl;
do
{
cin >> arr[i][j];
} while (arr[i][j] < 999 || arr[i][j] > 9999);
where i and j are in dec. in for loop. I just want to add check that input is not string or something like this. Cant rely on 2011 answer
Check out the below example.
All the magic happens inside to_num(), which will handle white space before and after the number.
#include <iostream>
#include <sstream>
#include <string>
#include <tuple>
auto to_num(const std::string& s)
{
std::istringstream is(s);
int n;
bool good = (is >> std::ws >> n) && (is >> std::ws).eof();
return std::make_tuple(n, good);
};
int main()
{
int n;
bool good;
std::cout << "Enter value: ";
for(;;)
{
std::string s;
std::getline(std::cin, s);
std::tie(n, good) = to_num(s);
if(good) break;
std::cout << s << " is not an integral number" << std::endl;
std::cout << "Try again: ";
}
std::cout << "You've entered: " << n << std::endl;
return 0;
}
Explanation of what's going on inside to_num():
(is >> std::ws >> n) extracts (optional) leading white space and an integer from is. In the boolean context is's operator bool() will kick in and return true if the extraction was successful.
(is >> std::ws).eof() extracts (optional) trailing white space and will return true if there is no garbage at the end.
UPDATE
Here is a slightly cleaner version that uses Structured binding declaration and Class template argument deduction available in c++17:
#include <iostream>
#include <sstream>
#include <string>
#include <tuple>
auto to_num(const std::string& s)
{
std::istringstream is(s);
int n;
bool good = (is >> std::ws >> n) && (is >> std::ws).eof();
return std::tuple(n, good); // look ma, no make_tuple
};
int main()
{
std::cout << "Enter value: ";
for(;;)
{
std::string s;
std::getline(std::cin, s);
auto [n, good] = to_num(s); // structured binding
if(good)
{
std::cout << "You've entered: " << n << std::endl;
break;
}
else
{
std::cout << s << " is not an integral number" << std::endl;
std::cout << "Try again: ";
}
}
return 0;
}
If you properly handle errors, you'll end up with a prompt / input loop that looks something like this:
#include <iostream>
#include <limits>
int getInput() {
while (true) {
std::cout << "Please enter a number between 80 and 85: ";
int number = 0;
std::cin >> number;
std::cout << "\n";
if (std::cin.eof()) {
std::cout << "Unexpected end of file.\n";
std::cin.clear();
continue;
}
if (std::cin.bad() || std::cin.fail()) {
std::cout << "Invalid input (error reading number).\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
continue;
}
if (number < 80 || number > 85) {
std::cout << "Invalid input (number out of range).\n";
continue;
}
return number;
}
// unreachable
return 0;
}
int main() {
int number = getInput();
std::cout << number << std::endl;
}
We can omit the range check if we don't need it.
We handle std::cin.eof() (e.g. user presses ctrl+Z on Windows) separately from the other conditions, since for eof there's nothing to ignore.
This follows the standard C++ stream behavior for whitespace and number conversion (i.e. it will accept inputs with extra whitespace, or inputs that only start with numeric values).
If we want more control over what we want to accept, or don't want conversion to depend on the locale, we have to use std::getline to read input from std::cin, and then do the string conversion ourselves (either with std::stringstream as in Innocent Bystander's answer, or using std::strtol, or std::from_chars).
I was typing this and it asks the user to input two integers which will then become variables. From there it will carry out simple operations.
How do I get the computer to check if what is entered is an integer or not? And if not, ask the user to type an integer in. For example: if someone inputs "a" instead of 2, then it will tell them to reenter a number.
Thanks
#include <iostream>
using namespace std;
int main ()
{
int firstvariable;
int secondvariable;
float float1;
float float2;
cout << "Please enter two integers and then press Enter:" << endl;
cin >> firstvariable;
cin >> secondvariable;
cout << "Time for some simple mathematical operations:\n" << endl;
cout << "The sum:\n " << firstvariable << "+" << secondvariable
<<"="<< firstvariable + secondvariable << "\n " << endl;
}
You can check like this:
int x;
cin >> x;
if (cin.fail()) {
//Not an int.
}
Furthermore, you can continue to get input until you get an int via:
#include <iostream>
int main() {
int x;
std::cin >> x;
while(std::cin.fail()) {
std::cout << "Error" << std::endl;
std::cin.clear();
std::cin.ignore(256,'\n');
std::cin >> x;
}
std::cout << x << std::endl;
return 0;
}
EDIT: To address the comment below regarding input like 10abc, one could modify the loop to accept a string as an input. Then check the string for any character not a number and handle that situation accordingly. One needs not clear/ignore the input stream in that situation. Verifying the string is just numbers, convert the string back to an integer. I mean, this was just off the cuff. There might be a better way. This won't work if you're accepting floats/doubles (would have to add '.' in the search string).
#include <iostream>
#include <string>
int main() {
std::string theInput;
int inputAsInt;
std::getline(std::cin, theInput);
while(std::cin.fail() || std::cin.eof() || theInput.find_first_not_of("0123456789") != std::string::npos) {
std::cout << "Error" << std::endl;
if( theInput.find_first_not_of("0123456789") == std::string::npos) {
std::cin.clear();
std::cin.ignore(256,'\n');
}
std::getline(std::cin, theInput);
}
std::string::size_type st;
inputAsInt = std::stoi(theInput,&st);
std::cout << inputAsInt << std::endl;
return 0;
}
Heh, this is an old question that could use a better answer.
User input should be obtained as a string and then attempt-converted to the data type you desire. Conveniently, this also allows you to answer questions like “what type of data is my input?”
Here is a function I use a lot. Other options exist, such as in Boost, but the basic premise is the same: attempt to perform the string→type conversion and observe the success or failure:
template <typename T>
auto string_to( const std::string & s )
{
T value;
std::istringstream ss( s );
return ((ss >> value) and (ss >> std::ws).eof()) // attempt the conversion
? value // success
: std::optional<T> { }; // failure
}
Using the optional type is just one way. You could also throw an exception or return a default value on failure. Whatever works for your situation.
Here is an example of using it:
int n;
std::cout << "n? ";
{
std::string s;
getline( std::cin, s );
auto x = string_to <int> ( s );
if (!x) return complain();
n = *x;
}
std::cout << "Multiply that by seven to get " << (7 * n) << ".\n";
limitations and type identification
In order for this to work, of course, there must exist a method to unambiguously extract your data type from a stream. This is the natural order of things in C++ — that is, business as usual. So no surprises here.
The next caveat is that some types subsume others. For example, if you are trying to distinguish between int and double, check for int first, since anything that converts to an int is also a double.
There is a function in c called isdigit(). That will suit you just fine. Example:
int var1 = 'h';
int var2 = '2';
if( isdigit(var1) )
{
printf("var1 = |%c| is a digit\n", var1 );
}
else
{
printf("var1 = |%c| is not a digit\n", var1 );
}
if( isdigit(var2) )
{
printf("var2 = |%c| is a digit\n", var2 );
}
else
{
printf("var2 = |%c| is not a digit\n", var2 );
}
From here
If istream fails to insert, it will set the fail bit.
int i = 0;
std::cin >> i; // type a and press enter
if (std::cin.fail())
{
std::cout << "I failed, try again ..." << std::endl
std::cin.clear(); // reset the failed state
}
You can set this up in a do-while loop to get the correct type (int in this case) propertly inserted.
For more information: http://augustcouncil.com/~tgibson/tutorial/iotips.html#directly
You can use the variables name itself to check if a value is an integer.
for example:
#include <iostream>
using namespace std;
int main (){
int firstvariable;
int secondvariable;
float float1;
float float2;
cout << "Please enter two integers and then press Enter:" << endl;
cin >> firstvariable;
cin >> secondvariable;
if(firstvariable && secondvariable){
cout << "Time for some simple mathematical operations:\n" << endl;
cout << "The sum:\n " << firstvariable << "+" << secondvariable
<<"="<< firstvariable + secondvariable << "\n " << endl;
}else{
cout << "\n[ERROR\tINVALID INPUT]\n";
return 1;
}
return 0;
}
I prefer to use <limits> to check for an int until it is passed.
#include <iostream>
#include <limits> //std::numeric_limits
using std::cout, std::endl, std::cin;
int main() {
int num;
while(!(cin >> num)){ //check the Input format for integer the right way
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "Invalid input. Reenter the number: ";
};
cout << "output= " << num << endl;
return 0;
}
Under C++11 and later, I have the found the std::stoi function very useful for this task. stoi throws an invalid_argument exception if conversion cannot be performed. This can be caught and handled as shown in the demo function 'getIntegerValue' below.
The stoi function has a second parameter 'idx' that indicates the position of the first character in the string after the number. We can use the value in idx to check against the string length and ascertain if there are any characters in the input other than the number. This helps eliminate input like 10abc or a decimal value.
The only case where this approach fails is when there is trailing white space after the number in the input, that is, the user enters a lot of spaces after inputting the number. To handle such a case, you could rtrim the input string as described in this post.
#include <iostream>
#include <string>
bool getIntegerValue(int &value);
int main(){
int value{};
bool valid{};
while(!valid){
std::cout << "Enter integer value: ";
valid = getIntegerValue(value);
if (!valid)
std::cout << "Invalid integer value! Please try again.\n" << std::endl;
}
std::cout << "You entered: " << value << std::endl;
return 0;
}
// Returns true if integer is read from standard input
bool getIntegerValue(int &value){
bool isInputValid{};
int valueFromString{};
size_t index{};
std::string userInput;
std::getline(std::cin, userInput);
try {
//stoi throws an invalid_argument exception if userInput cannot be
//converted to an integer.
valueFromString = std::stoi(userInput, &index);
//index being different than length of string implies additional
//characters in input that could not be converted to an integer.
//This is to handle inputs like 10str or decimal values like 10.12
if(index == userInput.length()) isInputValid = true;
}
catch (const std::invalid_argument &arg) {
; //you could show an invalid argument message here.
}
if (isInputValid) value = valueFromString;
return isInputValid;
}
You could use :
int a = 12;
if (a>0 || a<0){
cout << "Your text"<<endl;
}
I'm pretty sure it works.
I have the following code:
qstn:
cout << "Input customer's lastname: ";
getline(cin, lname);
if (lname.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ") != string::npos) {
cout << "You can only input alpha here!\n";
cin.clear();
goto qstn;
} else if (lname.empty()) {
cout << "Please enter your firstname!\n";
cin.clear();
goto qstn;
}
int lnamel = lname.length();
int strl = str.length();
int is = 0;
for (int i = 1; i < strl;) {
i++;
is++;
if (lname[i] == lname[is] && lname[i] == ' ' || lname[0] == ' ') {
cin.clear();
cout << "Please input your lastname properly!\n";
goto qstn;
}
}
// next question here
I'm having a hard time on thinking what will be the proper logic to avoid the
goto statement, since I was college I was using it but someone here said that
it's not good to use it at all cause it might ruin my code.
I tried using the do while loop but it's not smooth as goto.
Please help!
Here's an idiom I like to use:
int i;
if (std::cin >> prompt("enter an integer: ", i))
{
std::cout << "Read user input: " << i << "\n";
} else {
std::cout << "Input failed (too many attempts). Eof? " << std::boolalpha << std::cin.eof() << "\n";
}
Here, prompt is a smart input manipulator, that takes care of handling parse errors or stream failures and retrying.
It's quite generic so actually do many things, but you don't need to indicate all the options. When the manipulator is inserted into the stream it relays to the do_manip member:
template <typename Char, typename CharT>
friend std::basic_istream<Char, CharT>& operator>>(std::basic_istream<Char, CharT>& is, checked_input<T, Prompter>& manip) {
return manip.do_manip(is);
}
The do_manip handles all the logic without any gotos :) :
std::istream& do_manip(std::istream& is) {
auto attempt = [this] { return infinite() || retries_ > 0; };
while (attempt()) {
if (!infinite())
retries_ -= 1;
prompter_(out_);
if (is >> value_) {
if (!run_validators(out_))
is.setstate(is.rdstate() | std::ios::failbit);
else
break;
} else {
out_.get() << format_error_ << "\n";
}
if (attempt()) {
is.clear();
if (flush_on_error_)
is.ignore(1024, '\n');
}
}
return is;
}
You can see that there is a possibility to have validations run before accepting the input.
Here's a somewhat full-blown demo:
Live On Coliru
int main() {
using namespace inputmagic;
int i;
if (std::cin >> prompt("enter an integer: ", i)
.retries(3)
.flush_on_error(false)
.format_error("I couldn't read that (Numbers look like 123)")
.output(std::cerr)
.validate([](int v) { return v > 3 && v < 88; }, "value not in range (3,88)")
.validate([](int v) { return 0 == v % 2; })
.validate([](int v) { return v != 42; }, "The Answer Is Forbidden")
.multiple_diagnostics())
{
std::cout << "Read user input: " << i << "\n";
} else {
std::cout << "Input failed (too many attempts). Eof? " << std::boolalpha << std::cin.eof() << "\n";
}
}
You can see it will only accept valid integers
that are >3 and <88,
that are even
except 42 (forbidden number)
When entering the numbers 21, 42 and 10 on subsequent retries, you get: live
enter an integer: 21
Value not valid
enter an integer: 42
The Answer Is Forbidden
enter an integer: 10
Read user input: 10
However, if you enter 1 all the time you get this: live
enter an integer: 1
value not in range (3,88)
Value not valid
enter an integer: 1
value not in range (3,88)
Value not valid
enter an integer: 1
value not in range (3,88)
Value not valid
Input failed (too many attempts). Eof? false
Or if you read from a single line file: live
enter an integer: value not in range (3,88)
Value not valid
enter an integer: I couldn't read that (Numbers look like 123)
enter an integer: I couldn't read that (Numbers look like 123)
Input failed (too many attempts). Eof? true
Use a function:
bool getLastName(string & lname,
string & str)
{
cout << "Input customer's lastname: ";
getline(cin, lname);
if (lname.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ")
!= string::npos)
{
cout << "You can only input alpha here!\n";
cin.clear();
return false;
}
else if (lname.empty())
{
cout << "Please enter your firstname!\n";
cin.clear();
return false;
}
int lnamel = lname.length();
int strl = str.length();
int is = 0;
for (int i = 1; i < strl;)
{
i++;
is++;
if (lname[i] == lname[is] && lname[i] == ' ' || lname[0] == ' ')
{
cin.clear();
cout << "Please input your lastname properly!\n";
return false;
}
}
return true;
}
All I've done here is replace the gotos with return false. If the program makes it to the end of the function, return true. Make the function call in a while loop:
while (!getLastName(lname, str))
{
// do nothing
}
Not only does this de-spaghettify the code, but it breaks it up into nice, small, easy to manage pieces. This is called procedural programming.
A While loop looks like your best bet. You can redo the loop with the continue keyword.
int incorrect = 0;
while(!incorrect) {
cout<<"Input customer's lastname: ";
getline(cin,lname);
if(lname.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ")!=string::npos)
{
cout<<"You can only input alpha here!\n";
cin.clear();
continue;
}
else if(lname.empty())
{
cout<<"Please enter your firstname!\n";
cin.clear();
continue;
}
int lnamel=lname.length();
int strl=str.length();
int is=0;
for(int i=1; i<strl;)
{
i++;
is++;
if(lname[i]==lname[is]&&lname[i]==' '||lname[0]==' ')
{
cin.clear();
cout<<"Please input your lastname properly!\n";
continue;
}
incorrect = 1;
}
You need to use some do while loops
for instance this:
qstn:
cout<<"Input customer's lastname: ";
getline(cin,lname);
if(lname.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ")!=string::npos)
{
cout<<"You can only input alpha here!\n";
cin.clear();
goto qstn;
}
else if(lname.empty())
{
cout<<"Please enter your firstname!\n";
cin.clear();
goto qstn;
}
could be re-written as this:
int flag;
do{
flag = 1;
cout<<"Input customer's lastname: ";
getline(cin,lname);
if(lname.find_first_not_of( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ")!=string::npos)
{
flag = 0;
cout<<"You can only input alpha here!\n";
}
else if(lname.empty())
{
flag = 0;
cout<<"Please enter your firstname!\n";
}
cin.clear();
} while( flag !=1 );
feel free to use a boolean type flag, it doesn't really matter
It seems to me that your code suffers from lack of clarity of purpose.
You apparently don't want the string that's entered to include a leading space, nor multiple consecutive spaces. Other than that, only alphabetic characters should be accepted.
If the user does enter multiple consecutive spaces, I'd probably just ignore all but the first. I'd probably write the code something like this:
#include <string>
#include <iostream>
#include <algorithm>
#include <cctype>
#include <sstream>
bool non_alpha(std::string const &s) {
return !std::all_of(s.begin(), s.end(), [](unsigned char c) { return std::isalpha(c) || std::isspace(c); });
}
std::string get_name(std::string const &prompt) {
std::string result;
std::string line;
do {
std::cout << prompt;
std::getline(std::cin, line);
} while (non_alpha(line));
std::istringstream words(line);
std::string word;
while (words >> word)
result += word + ' ';
return result;
}
int main() {
auto res = get_name("Please enter last name, alpha-only\n");
if (res.empty())
std::cout << "Oh well, maybe some other time";
else
std::cout << "Thanks Mr(s). " << res << "\n";
}
I'd be tempted to consider doing roughly the same for non-alphabetic characters--rather than asking the user to re-enter from the beginning, assume it's a mistake and just ignore it.
I am having an issue trying to convert a number into a string. The purpose is for error checking to make sure the number is of a specific length. I have tried using both to_string() and convert.str() functions but get the same error back when trying to compile.
I am using MinGw g++ to compile and realize I need to tell it I want the C++11 standard, which I believe I have done. My compiler code is as follows:
NPP_SAVE
CD $(CURRENT_DIRECTORY)
C:\MinGW\bin\g++ -std=c++11 "$(FULL_CURRENT_PATH)" -o "$(NAME_PART).exe"
cmd /c $(NAME_PART).exe
Now assuming that is correct, my code for using to_string() is as follows:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
int book_code = 0;
cout << "Please enter the four digit book code: ";
cin >> book_code;
string code = to_string(book_code);
while (!(cin >> book_code) || code.length() != 4){
cin.clear();
cin.ignore(10000, '\n');
cout << "That is not a valid code." << endl;
cout << "Please enter the four digit book code: ";
}
}
And my code for using convert.str() is as follows:
int main() {
int book_code = 0;
cout << "Please enter the four digit book code: ";
cin >> book_code;
ostringstream Convert;
convert << book_code;
string code = convert.str();
while (!(cin >> book_code) || code.length() != 4){
cin.clear();
cin.ignore(10000, '\n');
cout << "That is not a valid code." << endl;
cout << "Please enter the four digit book code: ";
}
}
Neither of these was successful and both returned
error: 'to_string' was not declared in this scope
Am I missing something obvious?
In MinGW std::to_string() does not exist, you should declare your own implementation.
std::string to_string(int i)
{
std::stringstream ss;
ss << i;
return ss.str();
}
I recommend you to use MSYS2, it is more actualizated and you can avoid this type of problems.
Edit:
Checking the dot position in double:
#include <iostream>
#include <sstream>
#include <string>
std::string to_str_with_dot_pos(double i, unsigned int &pos)
{
std::stringstream ss;
ss << i;
std::string result(ss.str());
pos = 0;
while (pos < result.length() && result[pos] != '.') {
pos += 1;
}
return result;
}
int main(int argc, char **argv)
{
double d(12.54);
unsigned int pos(0);
// str should be "12.54".
// pos should be 2.
std::string str = to_str_with_dot_pos(d, pos);
std::cout << "double as string: " << str << std::endl;
std::cout << "double dot position: " << pos << std::endl;
return 0;
}
Explanation of the code (the while loop):
It gets every character of the std::string and checks if it does not equals to the . dot character, if the character is not equal to . it will add +1 to the pos variable.
It returns 2 and not 3 because we're counting from 0, not 1.
Also, this question is a duplicate.
Check that your version of MinGw support to_string, as the code above compiles correctly.
I'd recommend a different approach for length checking, one that avoids using strings:
#include <iostream>
#include <cmath>
using namespace std;
int is_len(int number, int len)
{
if(pow(10, len-1) <= number && number < pow(10, len))
return true;
return false;
}
int main()
{
int number = 1000;
cout << is_len(1, 2) << endl;
cout << is_len(1005, 4) << endl;
cout << is_len(9999, 4) << endl;
cout << is_len(599, 4) << endl;
cout << is_len(1005, 5) << endl;
return 0;
}
Prints:
0
1
1
0
0
I was typing this and it asks the user to input two integers which will then become variables. From there it will carry out simple operations.
How do I get the computer to check if what is entered is an integer or not? And if not, ask the user to type an integer in. For example: if someone inputs "a" instead of 2, then it will tell them to reenter a number.
Thanks
#include <iostream>
using namespace std;
int main ()
{
int firstvariable;
int secondvariable;
float float1;
float float2;
cout << "Please enter two integers and then press Enter:" << endl;
cin >> firstvariable;
cin >> secondvariable;
cout << "Time for some simple mathematical operations:\n" << endl;
cout << "The sum:\n " << firstvariable << "+" << secondvariable
<<"="<< firstvariable + secondvariable << "\n " << endl;
}
You can check like this:
int x;
cin >> x;
if (cin.fail()) {
//Not an int.
}
Furthermore, you can continue to get input until you get an int via:
#include <iostream>
int main() {
int x;
std::cin >> x;
while(std::cin.fail()) {
std::cout << "Error" << std::endl;
std::cin.clear();
std::cin.ignore(256,'\n');
std::cin >> x;
}
std::cout << x << std::endl;
return 0;
}
EDIT: To address the comment below regarding input like 10abc, one could modify the loop to accept a string as an input. Then check the string for any character not a number and handle that situation accordingly. One needs not clear/ignore the input stream in that situation. Verifying the string is just numbers, convert the string back to an integer. I mean, this was just off the cuff. There might be a better way. This won't work if you're accepting floats/doubles (would have to add '.' in the search string).
#include <iostream>
#include <string>
int main() {
std::string theInput;
int inputAsInt;
std::getline(std::cin, theInput);
while(std::cin.fail() || std::cin.eof() || theInput.find_first_not_of("0123456789") != std::string::npos) {
std::cout << "Error" << std::endl;
if( theInput.find_first_not_of("0123456789") == std::string::npos) {
std::cin.clear();
std::cin.ignore(256,'\n');
}
std::getline(std::cin, theInput);
}
std::string::size_type st;
inputAsInt = std::stoi(theInput,&st);
std::cout << inputAsInt << std::endl;
return 0;
}
Heh, this is an old question that could use a better answer.
User input should be obtained as a string and then attempt-converted to the data type you desire. Conveniently, this also allows you to answer questions like “what type of data is my input?”
Here is a function I use a lot. Other options exist, such as in Boost, but the basic premise is the same: attempt to perform the string→type conversion and observe the success or failure:
template <typename T>
auto string_to( const std::string & s )
{
T value;
std::istringstream ss( s );
return ((ss >> value) and (ss >> std::ws).eof()) // attempt the conversion
? value // success
: std::optional<T> { }; // failure
}
Using the optional type is just one way. You could also throw an exception or return a default value on failure. Whatever works for your situation.
Here is an example of using it:
int n;
std::cout << "n? ";
{
std::string s;
getline( std::cin, s );
auto x = string_to <int> ( s );
if (!x) return complain();
n = *x;
}
std::cout << "Multiply that by seven to get " << (7 * n) << ".\n";
limitations and type identification
In order for this to work, of course, there must exist a method to unambiguously extract your data type from a stream. This is the natural order of things in C++ — that is, business as usual. So no surprises here.
The next caveat is that some types subsume others. For example, if you are trying to distinguish between int and double, check for int first, since anything that converts to an int is also a double.
There is a function in c called isdigit(). That will suit you just fine. Example:
int var1 = 'h';
int var2 = '2';
if( isdigit(var1) )
{
printf("var1 = |%c| is a digit\n", var1 );
}
else
{
printf("var1 = |%c| is not a digit\n", var1 );
}
if( isdigit(var2) )
{
printf("var2 = |%c| is a digit\n", var2 );
}
else
{
printf("var2 = |%c| is not a digit\n", var2 );
}
From here
If istream fails to insert, it will set the fail bit.
int i = 0;
std::cin >> i; // type a and press enter
if (std::cin.fail())
{
std::cout << "I failed, try again ..." << std::endl
std::cin.clear(); // reset the failed state
}
You can set this up in a do-while loop to get the correct type (int in this case) propertly inserted.
For more information: http://augustcouncil.com/~tgibson/tutorial/iotips.html#directly
You can use the variables name itself to check if a value is an integer.
for example:
#include <iostream>
using namespace std;
int main (){
int firstvariable;
int secondvariable;
float float1;
float float2;
cout << "Please enter two integers and then press Enter:" << endl;
cin >> firstvariable;
cin >> secondvariable;
if(firstvariable && secondvariable){
cout << "Time for some simple mathematical operations:\n" << endl;
cout << "The sum:\n " << firstvariable << "+" << secondvariable
<<"="<< firstvariable + secondvariable << "\n " << endl;
}else{
cout << "\n[ERROR\tINVALID INPUT]\n";
return 1;
}
return 0;
}
I prefer to use <limits> to check for an int until it is passed.
#include <iostream>
#include <limits> //std::numeric_limits
using std::cout, std::endl, std::cin;
int main() {
int num;
while(!(cin >> num)){ //check the Input format for integer the right way
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "Invalid input. Reenter the number: ";
};
cout << "output= " << num << endl;
return 0;
}
Under C++11 and later, I have the found the std::stoi function very useful for this task. stoi throws an invalid_argument exception if conversion cannot be performed. This can be caught and handled as shown in the demo function 'getIntegerValue' below.
The stoi function has a second parameter 'idx' that indicates the position of the first character in the string after the number. We can use the value in idx to check against the string length and ascertain if there are any characters in the input other than the number. This helps eliminate input like 10abc or a decimal value.
The only case where this approach fails is when there is trailing white space after the number in the input, that is, the user enters a lot of spaces after inputting the number. To handle such a case, you could rtrim the input string as described in this post.
#include <iostream>
#include <string>
bool getIntegerValue(int &value);
int main(){
int value{};
bool valid{};
while(!valid){
std::cout << "Enter integer value: ";
valid = getIntegerValue(value);
if (!valid)
std::cout << "Invalid integer value! Please try again.\n" << std::endl;
}
std::cout << "You entered: " << value << std::endl;
return 0;
}
// Returns true if integer is read from standard input
bool getIntegerValue(int &value){
bool isInputValid{};
int valueFromString{};
size_t index{};
std::string userInput;
std::getline(std::cin, userInput);
try {
//stoi throws an invalid_argument exception if userInput cannot be
//converted to an integer.
valueFromString = std::stoi(userInput, &index);
//index being different than length of string implies additional
//characters in input that could not be converted to an integer.
//This is to handle inputs like 10str or decimal values like 10.12
if(index == userInput.length()) isInputValid = true;
}
catch (const std::invalid_argument &arg) {
; //you could show an invalid argument message here.
}
if (isInputValid) value = valueFromString;
return isInputValid;
}
You could use :
int a = 12;
if (a>0 || a<0){
cout << "Your text"<<endl;
}
I'm pretty sure it works.