MindlessMaik
MindlessMaik

Reputation: 291

extract numbers from string c++

I have a string, which looks like this:

foo
$RESULT :(0.2374742, 0.267722, ...up to a million more)
$STATES :{1, 3, 5, ...}
foo 

so somewhere in the string are results and directly after them are the states and I want to save the Results in a list and the states in another list.

I think I need something like "read from $RESULT :(" to ")" get every number and push to list, same for States, but I dont know how to read a String from "a" to "b" and tokenize its content.

Upvotes: 1

Views: 6764

Answers (6)

MindlessMaik
MindlessMaik

Reputation: 291

int index = s.find("RESULT: (");
int index2 = s.find("$STATE");

int length = index2 - index;

if (index != string::npos) {
    temp = s.substr(index + 7, length - 8);
}
typedef tokenizer<char_separator<char> > tokenizer;
char_separator<char> sep(",() ");
tokenizer tokens(temp, sep);
for (tokenizer::iterator tok_iter = tokens.begin();
        tok_iter != tokens.end(); ++tok_iter) {
    basic_string<char> tempValue = *tok_iter;

    values.push_back(tempValue);

}

Upvotes: 2

Roopesh Kohad
Roopesh Kohad

Reputation: 97

You can use strtok() library function - http://www.cplusplus.com/reference/clibrary/cstring/strtok.

Upvotes: 1

TVOHM
TVOHM

Reputation: 2742

#include <string>
#include <vector>
using namespace std;

int main()
{
  //This is your source string
  string Source = "foo $RESULT :(0.2374742, 0.267722) $STATES :{1, 3, 5} fo0";
  //Get the $RESULT section of the string, encapsulated by ( )
  string Results = Source .substr(Source .find("(") + 1, (Source .find(")") - Source .find("(")) - 1);

  //Get the $STATES section of the string, encapsulated by { }
  string States = Source .substr(Source .find("{") + 1, (Source .find("}") - Source .find("{")) - 1);

  vector<double> ResultsList;
  vector<int> StatesList;

  //While the Results string still has remaining ", " token/seperators in it
  while(Results.find(", ") != string::npos)  
  {
    //Get the next value and insert it into the vector (converting it from string to float using atof)
    ResultsList.push_back(atof(Results.substr(0, Results.find(", ")).c_str()));
    //Crop that off the oringal string
    Results = Results.substr(Results.find(", ") + 2);  
  }
  //Push the final value (no remaning tokens) onto the store
  ResultsList.push_back(atof(Results.c_str()));

  //Exactly the same operation with states, just using atoi to convert instead
  while(States .find(", ") != string::npos)  
  {  
    StatesList.push_back(atoi(States.substr(0, States .find(", ")).c_str()));  
    States = States.substr(States.find(", ") + 2);  
  }  
  StatesList.push_back(atoi(States.c_str()));
  return 0;
}

Upvotes: 0

Odinn
Odinn

Reputation: 808

Find the first acurance of the '(' and then the first of ')' sign and get the substring between the two indexes (first is the start and the length is end - start) and then you can do the same for the substring after the first ')' sign (for the states).

temp_str = input_str

do twice {
    start    = findChar(temp_str, '(');
    end      = findChar(temp_str, ')')
    len      = end - start + 1
    result   = substr(temp_str, start, len);  

    save_result_to_file(result)

    temp_str = substr(temp_str, end + 1);
}

Don't remember the exact c++ commands but you will have them for sure.

Upvotes: 0

CapelliC
CapelliC

Reputation: 60024

you could use boost tokenizer: it's a header only library, handy to use

Upvotes: 2

user1241335
user1241335

Reputation:

Tokenization in C++ is often done with getline, used so: getline(input stream, string where to save it, seperator character);

Try building a class for reading, that saves every line to a collection, then tokenize each line as needed and send to needed collections in an algorithm.

Upvotes: 1

Related Questions