简体   繁体   中英

How to extract floating point numbers from a string?

I need to read a line of text which contains letters, integers and floating point numbers and than calculate those floating point numbers. What I have done so far is below

           while (getline(readSearch, line))
    {
        while (line.find(letters[0])!=string::npos ||   line.find(letters[1])!=string::npos || line.find(letters[2])!=string::npos || line.find(letters[3])!=string::npos || line.find(letters[4])!=string::npos)
        {
            cout << line << "\n";
            break;
        }

Here is the file that I am reading from

   Chips 01c $0.50
   Juice  02j  $1.5
   Chocolate 03c $1.00
   Pen 04p 0.20
   Backpack 05b $30.00
   Bag 06b $35.25
   Ball 07b $10.50
   Toy 08t $15.22
   Wi-Fi Router 09wr $40.00
   Generic HDMI cable 010hc $4.00

Since this file contains three different types of data it is really hard for me to figure out how to calculate only those floating point numbers which are representing prices. I need to somehow input them to a variable and than perform calculation.

find the appropriate delimiter to locate the substr you're interested in, then use a stringstream to convert to float/double. There are equivalent std objects for wstring operations.

Since this file contains three different types

They you should define three different types. Define the input operator for each type. Then define a type for the row of data and you can just read in the three different types.

DataLine

struct DataLine
{
    std::string name;   // Wi-Fi Router
    DataBlob    blob;   // 010hc 
    Price       price;  // $40.00

    void swap(DataLine& other) noexcept
    {
        using std::swap;
        swap(name,   other.name);
        swap(blob,   other.blob);
        swap(price,  other.price);
    }

    friend std::istream& operator>>(std::istream& s, DataLine& data)
    {
        std::string line;
        if (std::getline(s, line))
        {
            // The name takes up all but the last two space separated words.
            // So find that point first.
            std::size_t  first  = line.find_last_of(" \t");
            std::size_t  second = (first == 0)
                                      ? std::string::npos 
                                      : line.find_last_of(" \t", first-1);
            std::stringstream lineStream(line);
            DataLine  tmp;
            if (lineStream >> ItemNameReader(tmp.name, second - 1) >> tmp.blob >> tmp.price) {
               // All three items were read correctly
               // So update the object with the new state.
               data.swap(tmp);
            }
            else {
               // One of the read operations failed.
               // So set the state of the stream to bad
               // The user can then handle this situation.
               s. setstate(std::ios::badbit);
            }
        }
        return s;
    }
};

ItemNameReader

struct ItemNameReader
{
    std::string&  name;
    std::size_t   size;
    ItemNameReader(std::string& name, std::size_t size)
        : name(name)
        , size(size)
    {}
    friend std::istream& operator>>(std::istream& s, ItemNameReader const& data)
    {
        data.name.resize(data.size);
        s.read(data.name.data(), data.size);
        return s;
    }   
};

DataBlob

class DataBlob
{
    std::string   blob;
    friend std::istream& operator>>(std::istream& s, DataBlob& data)
    {
        return s >> data.blob;
    }
};

Price

class Price
{
    char  units;
    float value;  // Though you may want to consider monetary
                  // units as integer values to avoid any rounding
                  // issues associated with floating point. 
    friend std::istream& operator>>(std::istream& s, Price& data)
    {
        return s >> data.units >> data.value;
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM