Sign in to follow this  

easy way to get numbers from a string

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys, I was wondering; what is a fast way to see if a particular string is a number? I'm parsing lines of input from the user, and if it is a number, I want it to do a certain thing. Once i determine whether or not it is a number, i can easily use atof()... p.s. no extra #include files, if possible.

Share this post


Link to post
Share on other sites
Pretty easy way is to subtract the value of '0' from the character. If it's less than 0, then you have an alpha character, otherwise it's the value of the number(i.e. '3' - '0' = 3)

so you could just iterate through:

if(char - '0' < 0)
// Alpha character
else
// Numeric character


You can also use the just use the stdio isalpha() function. :)

Share this post


Link to post
Share on other sites
Quote:
Original post by BTownTKD
true, but is there no stdlib function that could do that for me?

(sorry, I should have been more specific about "extra" include files. I am currently using <string>, <iostream>, and <stdlib>)


strtod(), strtol() are what you're after I think, defined in stdlib.

Share this post


Link to post
Share on other sites
You could use strtof and check the returned end pointer, i.e. verify that it's pointing at the null terminator and there's at least one character in the string.
It won't complain about initial whitespace however, so you'd have to add detection for that manually. Similarily you may want to ignore any whitespace at the end of the string.

A better way to handle whitespace (by ignoring it) may be to use sscanf with a 'canary' character at the end.
if(sscanf(string, "%lf %*c", &value) != 1) {
// error
}
At least I think that'd work..

edit: 10 seconds too late..

Share this post


Link to post
Share on other sites
In C++ this is easy, although it will require one more include file (why the resistance to this? Only the bits that are actually needed will get put into your exe, if you do the right stuff when compiling, and it's pretty small compared to the flat one-time cost of "the C++ CRT"):


// other includes - I noticed you have 'string', which is good
#include <sstream>
using namespace std;
// This checkes whether it is a number and also gets the number out if possible.

string input;
stringstream ss(input);
int value;
// As an added bonus, if we want to change the code to read hex numbers, for
// example, it's as easy as uncommenting this:
// ss << hex; // <-- that's a "stream manipulator"; the << gets translated into
// a call like "std::hex(ss)", which in turn tells this stringstream object
// to change its "reading mode" so that it assumes hex when looking for numbers.
// I don't think there exist manipulators for arbitrary number bases, however;
// but there are still many other useful things you can do here.

if (ss >> value) {
// there was a number at the beginning of the string, and now it is stored in
// value.
char garbage;
if (ss >> garbage) {
// if we get here, there is something after the number within the string.
// Maybe you don't want to do the 'number' handling in this case; maybe
// you do.
} else {
// we definitely have a number.
}
} else {
// the string definitely does not hold a number.
// The stringstream is now in a "fail state" just like cin is if you try
// to read a number when there isn't one, and similarly no data has been
// read from it. And naturally, 'value' is still uninitialized here.
}


If you're willing to go to Boost, they also provide a nice wrapper for this sort of process: boost::lexical_cast. It will throw an exception if the conversion cannot be done, and return the int (or whatever) as a new value if it can.

Share this post


Link to post
Share on other sites
I'm unsure of the performance of this, but here's yet another way:

#include <algorithm>	// for find_first_of
#include <iostream>
#include <string>

bool stringContainsNumber( std::string s ) {
const std::string numberSet( "0123456789" );

std::string::iterator it( std::find_first_of( s.begin(), s.end(), numberSet.begin(), numberSet.end() ) );
if( it != s.end() ) return true;
return false;
}

int main() {
std::string testString1( "This string contains no numbers" );
std::string testString2( "This string contains 1 number" );

if( stringContainsNumber( testString1 ) )
std::cout << "testString1 contains number(s)" << std::endl;

if( stringContainsNumber( testString2 ) )
std::cout << "testString2 contains number(s)" << std::endl;

return 0;
}


You could also use std::find_first_of(...) to get a number within a (alphanumeric) string, if that's what you're expecting.

Zahlman's suggestion is a little cleaner, though.

Share this post


Link to post
Share on other sites
That's ok except that it will (a) detect numbers with leading zeroes; (b) detect numbers too big to fit into an int; (c) not detect negative numbers. It will also only tell you where the first number starts, so you still have to go in and do the work of extracting the number. And anyway, complex searches are often better handled by a regex library (assuming a good understanding of regexes).

But yes, string::find_first_of() is a good tool to be aware of.

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this