0

I am a newbie to C++. I have a situation where the input integer is taken from the user. However, I need to check if the user enters a decimal value. How do I check this?

I have tried cin.good(), cin.fail() but they are detecting only non-digit entries and not decimal numbers. Any help would be appreciated.

#include <iostream>

int main()
{
  using namespace std;
  int x;
  cout << "Enter an integer: " << endl;
  cin >> x;

  if (cin.good()) {
    cout << "input is an integer" << endl;
  }
  else 
    cout << "input is not an integer" << endl;
}

Here's my output:

1.

Enter an integer: 
1.2
input is an integer

2.

Enter an integer: 
a
input is not an integer
Biffen
  • 6,249
  • 6
  • 28
  • 36
skt9
  • 1
  • 1
  • 1
  • Can't you just check if the input is equal to its floor ? – Irminsul Jun 27 '16 at 07:42
  • 1
    why not read it as a float and check it for decimal and then cast it to integer? – ryanafrish7 Jun 27 '16 at 07:42
  • for reference http://stackoverflow.com/questions/22858398/how-to-show-float-if-the-user-inputs-a-digit-with-a-decimal-and-int-if-the-user – default Jun 27 '16 at 07:43
  • you can simply use casting http://i.imgur.com/PKB3FB1.png – Mohamed Slama Jun 27 '16 at 08:16
  • 1
    @MohamedSlama: Sure, if correctness is not one of your primary goals. – IInspectable Jun 27 '16 at 08:18
  • @Benoit, OutofRange thank you! My bad, I never thought of that! By the way, aren't cin.good() and cin.fail() used for the same purpose,i.e to check if the user input matches/is different from the datatype of the variable? Please correct me if I am wrong. – skt9 Jun 27 '16 at 08:41

3 Answers3

1
float x = 4.2;
if (x == (int) x)
{
    // int
}
else
{
    // not int
}
Christian Neverdal
  • 5,655
  • 6
  • 38
  • 93
Ivan Rubinson
  • 3,001
  • 4
  • 19
  • 48
  • 1
    Consider using [`std::floor`](http://en.cppreference.com/w/cpp/numeric/math/floor) instead of the C-style cast, or if you _really_ want to cast use `static_cast` :) – Rakete1111 Jun 27 '16 at 11:04
1

You can use std::isdigit for checking your string input next way.

  bool is_numeric(const std::string& str)
  {
     std::string::const_iterator it = str.begin();
     if (it != str.end() && *it == '-') ++it;
     if (it == str.end()) return false;
     while (it != str.end() && std::isdigit(*it)) ++it;
     return it == str.end();
  }

It's not hard to change it to work with floating points, if needs, but that function will exactly checks what you need.

Arkady
  • 2,084
  • 3
  • 27
  • 48
0

You receive the input as an int from cin and hence any float entered would already be truncated by the time you get your hands on it. You should receive it as a float or a string to decide on the validity of the input.

Removed the earlier answer since it went down the slippery route of manually parsing the input which is unnecessary and error-prone. The standard library already has multiple ways to check if an input is a valid number. Two ways that I know: C++ streams and the C library function strtof. Here's an example using the latter:

#include <iostream>
#include <string>
#include <cmath>

bool is_int(float f) {
    return std::floor(f) == f;
}    

int main()
{
    std::cout << "Enter an integer: ";
    std::string input;
    std::cin >> input;
    char *e = nullptr;
    char const *str = input.c_str();
    float const f = strtof(str, &e);
    // no conversion was performed or was stopped as disallowed
    // characters were encountered: Not A Number
    if ((e == str) || (*e != '\0'))
        std::cout << "NAN";
    else if ((f == HUGE_VALF) || !std::isfinite(f))
        std::cout << "too large";
    else
        std::cout << (is_int(f) ? "integer" : "non-integer");
    std::cout << '\n';
}

Live example.

To check if the input is a number, this

float f;
cin >> f;

is possible too, but it will also accept NANs as valid input e.g. 45dsf will be converted to 45. One has to then check if the conversion happened completely and successfully by checking the fail and eof bits of the stream.

See also

Community
  • 1
  • 1
legends2k
  • 31,634
  • 25
  • 118
  • 222
  • `Enter an integer:` - `a` - `input is an integer` – IInspectable Jun 27 '16 at 08:08
  • Of course, further validations are needed, the answer was for what the question specifically asked for: "that the input doesn't contain a decimal". A real-world program should be doing lot more through checks e.g. digit separators. – legends2k Jun 27 '16 at 08:10
  • I didn't make this up. This is sample input from the original question. An answer should be capable of dealing with sample input provided by the OP. – IInspectable Jun 27 '16 at 08:12
  • 1
    @legends2k `isNumber` produces UB on empty string and gives [discutable results on some inputs](http://ideone.com/LAhDz0). – Hiura Jun 27 '16 at 09:51
  • @IIns I don't know your definition of what an answer should be like, but I know that not even giving a solution and pointing to the right direction would do; [see the help centre](http://stackoverflow.com/help/how-to-answer): _Any answer that gets the asker going in the right direction is helpful._ Giving a 100% correct, working solution in just an answer box is impractical and impossible, we've libraries to do that. – legends2k Jun 27 '16 at 14:24
  • @Hiura So, what's your point? Untested code is written for teaching something to give a feel for such things and no one claims it's production quality checked-in code. Helping the OP will do, completing his/her task isn't need and not encouraged anyways. – legends2k Jun 27 '16 at 14:26
  • I see, thanks for your comments, made me learn a few things. – legends2k Jun 28 '16 at 06:15