get atof to continue converting a string to a number after the first non valid ch in a string
i'd like to know if there a way to get atof continue converting to number even if there are non valid charcters in the way
for example let say i have string "444-3-3-33" i want to covert 开发者_运维知识库it to a double a=4443333 (and keep the string as it was) happy to get any suggestions or an alternative way
thanks!
I can't take credit for this solution, though it's a good one, see this SO post. For those too lazy to skip over, the author recommends using a locale to treat all non-numeric digits as whitespace. It might be overkill for your solution but the idea is easily adaptable. Instead of all non-numeric, you could just use "-" as your whitespace. Here's his code, not mine. Please, if you like this give him the upvote.
struct digits_only: std::ctype<char>
{
digits_only(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table()
{
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::space);
std::fill(&rc['0'], &rc['9'], std::ctype_base::digit);
return &rc[0];
}
};
bool in_range(int lower, int upper, std::string const &input) {
std::istringstream buffer(input);
buffer.imbue(std::locale(std::locale(), new digits_only()));
int n;
while (buffer>>n)
if (n < lower || upper < n)
return false;
return true;
}
Then just remove the whitespace and pass the string to atof
.
Both of the following strip out non-digits for me
bool no_digit(char ch) {return !std::isdigit(ch);}
std::string read_number(const std::string& input)
{
std::string result;
std::remove_copy_if( input.begin()
, input.end()
, std::back_inserter(result)
, &no_digit);
return result;
}
std::string read_number(std::istream& is)
{
std::string result;
for(;;) {
while(is.good() && !std::isdigit(is.peek()))
is.get();
if(!is.good())
return result;
result += is.get();
}
assert(false);
}
You can then read number using string streams:
std::istringstream iss(read_number("444-3-3-33");
int i;
if( !(iss>>i) ) throw "something went wrong!";
std::cout << i << '\n';
I would recommend sscanf
[edit]
upon further review, it would seem that you'll have to use strstr
as sscanf
could have an issue with the embedded '-'
further, the page should give you a good start on finding (and removing) your '-' char's
[/edit]
copy the 'string number' to a local buffer(a std::string
), then strip out the accepted chars from the number(compressing the string, as to not leave blank space, thus using std::string.replace
), then call atof
on std::string.c_str
. alternatly you can use c strings, but then this wouldn't be C++.
alternatively, create a custom version of atof your self, using the source from say stdlibc or basic math.
精彩评论