# Probably simple C++ question

This topic is 3920 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I an trying to input a variable with type double but don't know how to check to make sure the input is double and not something else. Could someone tell me how to do this?

##### Share on other sites
Quote:
 Original post by PCosmin89What about if(variable%1!=0)

Umm, no. Modular arithmetic only works on integral types (int, short, long, etc) in C++, and even if that was allowed, what if the value was 10.0?

##### Share on other sites
Quote:

% is only valid for integers. This doesn't answer the question.

Quote:
 Could someone tell me how to do this?

Presuming you are using std::cin for input, then just:
double d = 0.0;std::cin >> d;

Now, if you want to make sure the user enters something that is, in fact, a double (in the above code if they enter somebody bogus you will get unexpected results), you must first read the input as a string, then parse it. boost::lexical_cast is great for this. If you don't have Boost, get it. Or use something like
bool is_double(const std::string &input){  std::istringstream marshaller(input);  double dummy;  marshaller >> dummy;  return !marshaller.fail();}

##### Share on other sites
Quote:
 Original post by jpetrieOr use something likebool is_double(const std::string &input){ std::istringstream marshaller(input); double dummy; marshaller >> dummy; return !marshaller.fail();}

This is actually no different from
double x;if (cin >> x) {    // ok}else {    // bad}

In that both will seem ok if the user enters something like "42asdf" -- x = 42, but "asdf" will still be left in the buffer. If you really need to verify that what the user entered is a real number and absolutely nothing else, that's kinda difficult. You can use atof, but that returns 0.0 in case of an error. So you'd have to compare it to the stringstream conversion result, to make sure that the user didn't actually enter 0.

##### Share on other sites

// Evaluates whether a "C" string is a real.bool isReal(const char ch[]){    unsigned i = 0;    bool has_point = false, has_sign = false;    while ( ch != '\0' )    {        // Look for a digit.        if ( !std::isdigit(ch) )        {            switch (ch)            {                case '.':                    if ( has_point == true )                    {                        // Oops, allowed one occurrence.                        return false;                    }                    else                    {                        // Found the first point.                        has_point = true;                    }                    break;                case '-':                    if ( has_sign == true )                    {                        // Oops, allowed one occurrence.                        return false;                    }                    else                    {                        // Found the first sign.                        has_sign = true;                    }                    break;                case '+':                    if ( has_sign == true )                    {                        // Oops, allowed one occurrence.                        return false;                    }                    else                    {                        // Found the first sign.                        has_sign = true;                    }                    break;                default:                    // Oops, no number, no point, no minus, no plus.                    return false;            }        }        ++i;    }    // Has point, sign and at least one number.    if ( has_point && has_sign && i > 2 )        return true;    // Has point and at least one number.    if ( has_point && i > 1 )        return true;    // Has number, but nothing else.    return false;}

Rules:

1. Can have either a + or - sign or none, but not both signs, or it fails.
2. Must have decimal point, or else assumed to be an integer, and it fails.
3. Must have at least one digit, or it fails.
4. If it has anything other than +/-, digits and a point, then it fails.

--random

##### Share on other sites
Quote:
 Original post by random_thinkerHow about...*** Source Snippet Removed ***Rules:1. Can have either a + or - sign or none, but not both signs.2. Must have decimal point, or else assumed to be an integer.3. Must have at least one number.4. If it has anything other than +/-, digits and a point, then it fails.--random

Consider:
45.+0

##### Share on other sites
Quote:
Original post by drakostar
Quote:
 Original post by jpetrieOr use something likebool is_double(const std::string &input){ std::istringstream marshaller(input); double dummy; marshaller >> dummy; return !marshaller.fail();}

This is actually no different from
*** Source Snippet Removed ***
In that both will seem ok if the user enters something like "42asdf" -- x = 42, but "asdf" will still be left in the buffer. If you really need to verify that what the user entered is a real number and absolutely nothing else, that's kinda difficult. You can use atof, but that returns 0.0 in case of an error. So you'd have to compare it to the stringstream conversion result, to make sure that the user didn't actually enter 0.

It is quite different. Your one tries to interpret a double straight from std::cin, which if it fails you must reset the streams state and possibly ignore characters from the stream. I prefer to read in a string and then do the conversion as a separate step.

@random_thinker

what about "3E-3". Also, why not std::string?

##### Share on other sites
If you want to check that there are no additional characters left in the string after reading the double, you can add a check to jpetrie's solution:
bool is_double(const std::string &input) {  std::istringstream marshaller(input);  double dummy;  marshaller >> dummy;  return !marshaller.fail() && (marshaller.rdbuf()->in_avail() == 0);}

##### Share on other sites
Quote:
 Consider:45.+0

Quote:
 what about "3E-3". Also, why not std::string?

Good points, could alter the logic to allow signs only at the beginning of the sequence to solve this potential problem. However, it is a lightweight and reliable approach even though it's very C-like. I couldn't be bothered to permit 'E-3' type constructs.

Could use std::string if you wanted, with a few alterations. I have used this primarily with std::getline() and feed the resulting string.c_str() to it.

--random

What about something like:

// Declare a double.double d=0;// Reference character set.const std::string double_chars("0123456789Ee-+.");// Make a cache.std::string cache; // Fill the cache.std::getline(std::cin,cache);// Check for any non-double characters.if (cache.find_first_not_of(double_chars) == std::string::npos){       // All characters are in reference set.     d=strtod(cache.c_str(),0);}else{     // Fail.}

[Edited by - random_thinker on September 28, 2007 5:56:17 PM]

1. 1
2. 2
3. 3
4. 4
Rutin
17
5. 5

• 12
• 9
• 12
• 37
• 12
• ### Forum Statistics

• Total Topics
631419
• Total Posts
2999984
×