How to check if a number (double type) stored as a string is a valid double number in C ++?

I have a problem with a program I'm working on in C ++. I ask the user to enter a valid number. I perceive this as a string, because I am doing a specific task, this simplifies the work in the end. For basic error checking, I want to check if the entered number is really a valid number. Example:

Enter number: 3.14 This would be valid Enter number: 3.1456.365.12 This shouldn't be valid 
+7
c ++ types
source share
11 answers

use strtod, which converts the string to double and returns any characters that it cannot interpret as part of the double.

 double strtod(const char* nptr, char** endptr) 

Like this:

 char* input = "3.1456.365.12"; char* end; strtod(input, &end); if (*input == '\0') { printf("fail due to empty string\n"); } if (end == input || *end != '\0') { printf("fail - the following characters are not part of a double\n%s\n", end); } 
+9
source share

I think boost :: lexical_cast should help you here

+7
source share

An example of using only standard C ++:

 #include <sstream> // ... double dbl = 0.0; std::istringstream num("3.1456.365.12"); num >> dbl; if(!num.fail() && num.eof()) // This second test is important! This makes sure that the entire string was converted to a number { // success } else { // failure } 

Option function of the Bonus template:

 #include <sstream> #include <string> #include <exception> // Version that throws an exception on a bad parse: template <typename T> T parse(const std::string& str) { T value; std::istringstream parser(str); parser >> value; if(!parser.fail() && parser.eof()) { return value; } else { throw "bad lexical cast"; } } // usage: double foo = parse<double>("3.14234"); // Non-exception, error code version template <typename T> bool parse(const std::string& str, T& value) { std::istringstream parser(str); parser >> value; return (!parser.fail() && parser.eof()); } // usage: double foo = 0.0; bool success = parser<double>("3.11234", foo); 
+4
source share

If you donโ€™t have a promotion, you can always use strtod

+3
source share

You can use strtoX (where X is f for float, l for long, ul for unsigned long, etc.) by selecting the desired number. One of the parameters you give it is the "end pointer", which points to the first character in the string, which cannot be converted to the type of the target number.

In your case, you are apparently looking for the end pointer to be at the end of the string, indicating that all characters in the string have been converted to the target type.

Edit: Sorry, didnโ€™t notice that you mentioned the โ€œdoubleโ€ in the title (but not the question itself). In this case, you would use strtod , as advised by a few others.

+3
source share

The best way is to make a real attempt to convert your string to double using any of the standard and / or idiomatic methods of performing the conversion and subsequently check for errors. In C, which will function from the strto... group (which, of course, is perfectly used in C ++ as well). In C ++, you can use the stream-based conversion idiom.

One thing that you need to pay attention to is that the general convention in standard conversion methods is to convert "as much as possible" and not treat extra characters as an error. For example, the string โ€œ123abcโ€ is usually considered valid input, with only the โ€œ123โ€ part being converted. All the methods used provide you with a way to discover the fact that there is something extra after the actual number if you want to treat this situation as an error. But you need to take additional steps to complete this check.

+2
source share

A simple option is to use the sscanf function:

 const char * num_as_str = "3.1416"; double num; if(std::sscanf(num_as_str, "%lg", &num) == 1) { std::cout << "You correctly entered the number " << num << "\n"; } 

If you want a fantasy, you can use istringstream:

 std::istringstream iss(num_as_str); if(iss >> num) { std::cout << "You correctly entered the number " << num << "\n"; } 

If you want extra fantasy, you can use boost lexical_cast:

 try { num = boost::lexical_cast<double>(num_as_str); } catch(boost::bad_lexical_cast &) { std::cout << "What you entered is not a proper number" << num << "\n"; } 
+1
source share

Ah, I loved these assignments. A good old manual lexer is the way to go (since you're still in the early days - don't try to use boost yet). They are fast, easy to write and very fun to play. If you can get a copy of Levinโ€™s book on Lex / Yacc, find the first couple of chapters for ideas.

0
source share

As mentioned by AndreyT, the best way is to try to convert the string to float and check for an error. Personally, I would prefer to use std :: istringstream since you are using C ++. Something like the following should work:

 float ff; std::istringstream istr; std::string input("1234.5678"); // set the stream to have your string as its base istr.str(input); // now try to read the number: istr >> ff; if (istr.fail()) { // some error in the parsing } 

istringstream is part of the STL, so you do not need any additional libraries, as well as with exceptions, if this is your choice. More information can be found here: http://www.cplusplus.com/reference/iostream/istringstream/

0
source share

You can use regular expressions. Since you already have a string, it would be easy to compare this with this regex:

 /^\d+(\.\d+)?$/ 

The regex.h library can help you here. See this: regex.h

0
source share

This is my quick hack :)

 #include <iostream> #include <string> #include <sstream> using namespace std; template <typename T> bool fromStr(const std::string& str, T& var) { std::stringstream convertor; convertor << str; convertor >> var; if( convertor.fail() ) return false; char c = static_cast<char>( convertor.get() ); return convertor.eof() || c == '\n' || c == ' ' || c == '\t'; } int main() { double d; std::string str = "5.04146.55"; if( fromStr<double>(str, d) ) { std::cout << "Valid conversion!, d = " << d; } else { std::cout << "Invalid conversion!"; } } 
0
source share

All Articles