I want to extract integers from a certain string in order to perform mathematical operations on them.
For example for a string
25 1 3; 5 9 2; 1 3 6
I only want to extract
25, 1, 3, 5, 9, 2, 1, 3, 6
is there a way I can do that?
I want to extract integers from a certain string in order to perform mathematical operations on them.
For example for a string
25 1 3; 5 9 2; 1 3 6
I only want to extract
25, 1, 3, 5, 9, 2, 1, 3, 6
is there a way I can do that?
I would just use the String Toolkit to parse the strings using spaces, brackets and semicolon as the delimiters.
I have answered the questions before Extract Data from a line
I paraphrased that code below:
#include <strtk.hpp> // http://www.partow.net/programming/strtk
std::string src = "[25 1 3; 5 9 2; 1 3 6]";
std::string delims(" [];");
std::vector<int> values;
strtk::parse(src, delims, values );
// values will contain all the integers in the string.
// if you want to get floats & integers the vector needs to be float
There are many various methods for doing that. For example you can use <regex>
and pick them, but I think extracting from string stream will be easier.
void extractIntegerWords(string str)
{
stringstream ss;
/* Storing the whole string into string stream */
ss << str;
/* Running loop till the end of the stream */
string temp;
int found;
while (!ss.eof()) {
/* extracting word by word from stream */
ss >> temp;
/* Checking the given word is integer or not */
if (stringstream(temp) >> found)
cout << found << " ";
/* To save from space at the end of string */
temp = "";
}
}
// Driver code
int main()
{
string str = "25 1 3; 5 9 2; 1 3 6";
extractIntegerWords(str);
return 0;
}
Code taken from here: Extract integers from string
if you want to extract them from a string having any content (you do not know what are the other characters) you can use a stringstream
For instance supposing the number are int and wanted the extracted int in a list :
#include <sstream>
#include <iostream>
#include <string>
#include <list>
int main(int argc, char ** argv)
{
if (argc == 2) {
std::stringstream iss(argv[1]);
std::list<int> l;
for (;;) {
int v;
if (iss >> v)
// ok read an int
l.push_back(v);
else {
// was not an int, clear error
iss.clear();
// try to read a string to remove non digit
std::string s;
if (!(iss >> s))
// EOF, end of the initial string
break;
}
}
for (auto v : l)
std::cout << v << ' ';
std::cout << std::endl;
}
return 0;
}
Compilation and execution :
pi@raspberrypi:~ $ g++ -pedantic -Wall -Wextra c.cc
pi@raspberrypi:~ $ ./a.out "25 1 3; 5 9 2; 1 3 6"
25 1 3 5 9 2 1 3 6
pi@raspberrypi:~ $
Note in that solution "123 a12 13" will produce 123 and 13, not 123 12 13.
To produce 123 12 13 from "123 a12 13" just read a character rather than a string in case of an error :
#include <sstream>
#include <iostream>
#include <string>
#include <list>
int main(int argc, char ** argv)
{
if (argc == 2) {
std::stringstream iss(argv[1]);
std::list<int> l;
for (;;) {
int v;
if (iss >> v)
l.push_back(v);
else {
iss.clear();
char c;
if (!(iss >> c))
break;
}
}
for (auto v : l)
std::cout << v << ' ';
std::cout << std::endl;
}
return 0;
}
Compilation and execution :
pi@raspberrypi:~ $ g++ -pedantic -Wall -Wextra c.cc
pi@raspberrypi:~ $ ./a.out "25 1 3; 5 9 2; 1 3 6"
25 1 3 5 9 2 1 3 6
pi@raspberrypi:~ $ ./a.out "123 a12 13"
123 12 13
A one pass solution can scan the string looking for a range starting with the next digit available and stopping where there is a non-digit character. Then create an integer from the characters in the range and continue until the end of the string is reached.
vector<int> extract_ints( std::string const& str ) {
auto& ctype = std::use_facet<std::ctype<char>>(std::locale{});
auto p1 = str.data(), p2 = str.data();
vector<int> v;
for (auto e = &str.back() + 1; p1 < e; p1++) {
p1 = ctype.scan_is( ctype.digit, p1, e );
p2 = ctype.scan_not( ctype.digit, p1 + 1, e );
int x = 0;
while (p1 != p2) {
x = (x * 10) + (*p1 - '0');
p1++;
}
v.push_back(x);
}
return v;
}
Example:
auto v = extract_ints("[1,2,3]");
for (int i=0; i<v.size(); i++)
cout << v[i] << " ";
Output:
1 2 3