Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extraction of integers from strings

Tags:

c++

string

int

What is the best and shortest way to extract integers from a string and save them to an array of integers?

Sample string " 65 865 1 3 5 65 234 65 32 #$!@#"

I tried taking look at some other posts but couldn't find one about this specific issue... Some help and explanation would be great.

like image 372
Ezz Avatar asked Dec 13 '25 08:12

Ezz


2 Answers

It seems this can all be done with std::stringstream:

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

int main() {
    std::string str(" 65 865 1 3 5 65 234 65 32 #$!@#");
    std::stringstream ss(str);
    std::vector<int> numbers;

    for(int i = 0; ss >> i; ) {
        numbers.push_back(i);
        std::cout << i << " ";
    }
    return 0;
}

Here is a solution that accounts for non digits between numbers:

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;

struct not_digit {
    bool operator()(const char c) {
        return c != ' ' && !std::isdigit(c);
    }
};

int main() {
    std::string str(" 65 865 1 3 5 65 234 65 32 #$!@# 123");
    not_digit not_a_digit;
    std::string::iterator end = std::remove_if(str.begin(), str.end(), not_a_digit);
    std::string all_numbers(str.begin(), end);
    std::stringstream ss(all_numbers);
    std::vector<int> numbers;

    for(int i = 0; ss >> i; ) {
        numbers.push_back(i);
        std::cout << i << " ";
    }
    return 0;
}
like image 183
andre Avatar answered Dec 14 '25 21:12

andre


Because of the complexities of the delimiters here (you seem to have spaces and non-numeric characters) I'd use the string splitting available in the boost library:

http://www.boost.org/

This allows you to split using regular expressions as delimiters.

First, pick the delimiter which is a regular expression:

boost::regex delim(" "); // I have just a space here, but you could include other things as delimiters.

Then extract as follows:

std::string in(" 65 865 1 3 5 65 234 65 32 ");
std::list<std::string> out;
boost::sregex_token_iterator it(in.begin(), in.end(), delim, -1);
while (it != end){
    out.push_back(*it++);
}

So you can see I've reduced it to a list of strings. Let me know if you need to do the whole step to an array of integers (not sure what array type you want); happy to include that too if you want to go the boost way.

like image 21
Bathsheba Avatar answered Dec 14 '25 22:12

Bathsheba