Reputation: 544
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.
Upvotes: 3
Views: 20213
Reputation: 7249
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;
}
Upvotes: 4
Reputation: 114
I like to use istringstream
for this
istringstream iss(line);
iss >> id;
Since it is a stream, you can use it just like cin
By default, it uses space as a delimiter. You can simply wrap this in a loop and then cast the resulting string
as an int
.
http://www.cplusplus.com/reference/sstream/istringstream/istringstream/
Upvotes: 0
Reputation: 27262
You can us a stringstream to hold you string data and the read it out into integers using the typical C++ iostream mechanisms:
#include <iostream>
#include <sstream>
int main(int argc, char** argv) {
std::stringstream nums;
nums << " 65 865 1 3 5 65 234 65 32 #$!@#";
int x;
nums >> x;
std::cout <<" X is " << x << std::endl;
} // => X is 65
This'll spit out the first number, 65. Getting the data clean will be another matter. You can check
nums.good()
to see if the read into an int was successful.
Upvotes: 0
Reputation: 234885
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:
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.
Upvotes: 1