float out of string

Hello everyone,


How to get float out of const char* eva="I am number 1000.235 abcd"
i need to extract 1000.235.

Thanks
There are lexical casts for std::string or functions like stof()
Do you have to work with const char* or would std::string be an alternative?
i can work with std::string
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
using namespace std;


double extractDouble( string text )
{
   const string digits = "0123456789";
   double x = 0.0;

   unsigned ipos = text.find_first_of( digits );
   if ( ipos != string::npos ) stringstream( text.substr( ipos ) ) >> x;
   else                        cout << "No number found\n";

   return x;
}


int main()
{
   cout << fixed << setprecision( 3 );
   cout << extractDouble( "I am number 1000.235 abcd" );
}

@lastchance

might be better with :

const string digits = "0123456789.+-"; // decimal point signs

Edit:

Pedantically I was going to add e and E : e3 for example, is a valid double with the value 0.0

But now though, there are problems if ( . + - e E ) exist and aren't part of a number.

Maybe the assignment is more of a challenge: maybe it needs a state machine :+)
Last edited on
@TheIdeasMan,

might be better with :
const string digits = "0123456789.+-"; // decimal point signs


You're absolutely right!

+- signs, anyway; decimal point might get mixed up with a full stop.
Last edited on
You'd still want to check if the conversion was successful, no?

"-wyz.+z".

You can have a valid digit without (-/+/.) be a valid number, but you can't have (-/+/.) without a valid digit be a valid number. Kinda feels like we're reinventing the wheel.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
#include <regex>

int main()
{
    // decimal number in fixed format (99 -99. +99.999 -.999 -3 etc.)
    // prefixed by beginning of string or white space
    // with an optional + or -
    // suffixed by end of string or white space
    std::regex num_re( "(?:^|\\s)[+-]?(?:\\d+\\.?\\d*|\\d*\\.?\\d+)(?:\\s|$)" ) ;

    const char* eva = "I a.m ++7.8 6nu+m-7ber+8 -1000.235 abcd" ;
    
    std::cmatch match ;
    if( std::regex_search( eva, match, num_re ) )
    {
        const double value = std::stod( match[0] ) ;
        std::cout << "found " << std::fixed << value << '\n' ;
    }
    else std::cout << "regex_search failed\n" ;
}

http://coliru.stacked-crooked.com/a/1bb5f76ba335c27e

With std::string, use std::smatch (instead of std::cmatch)
A loop usage of stringstream is OK I think:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;

vector<double> extractDouble( string text )
{
   const string digits = "0123456789.+-eE";
   double x = 0.0;
   vector<double> values;
   stringstream ss;
   ss.str(text);

   while (ss.rdbuf()->in_avail()) {
        ss >> x;
        if (ss.good() || ss.eof()) values.push_back(x);
        else if (ss.bad()) break;
        else if (ss.fail()) {
            ss.clear();
            ss.rdbuf()->sbumpc();
        }
   }
   return values;
}


int main()
{
   cout << fixed << setprecision( 3 );
   auto r = extractDouble( "1I99like 00+100 -5dogs -99.,and -3.14 cats'+99.999 "
                  "price+2. *-.999 aaa-3 USA+7e2# -6E3 ->..safari -.11e4 .1E3 1.e3Eetc. 137" );
   std::copy(r.begin(), r.end(), ostream_iterator<double>(cout,", "));
}
Last edited on
std::regex num_re( "(?:^|\\s)[+-]?(?:\\d+\\.?\\d*|\\d*\\.?\\d+)(?:\\s|$)" );

Ох ебаться-сраться!
Does it really work?! Cool!
Registered users can post here. Sign in or register to post.