【发布时间】:2019-09-14 06:38:29
【问题描述】:
我想从某个字符串中提取整数,以便对它们执行数学运算。
例如对于一个字符串
25 1 3; 5 9 2; 1 3 6
我只想提取
25、1、3、5、9、2、1、3、6
有什么办法可以做到吗?
【问题讨论】:
-
是的,您可以使用正则表达式来挑选由其他数字以外的其他数字分隔的数字。
标签: c++
我想从某个字符串中提取整数,以便对它们执行数学运算。
例如对于一个字符串
25 1 3; 5 9 2; 1 3 6
我只想提取
25、1、3、5、9、2、1、3、6
有什么办法可以做到吗?
【问题讨论】:
标签: c++
我只会使用String Toolkit 来解析字符串,使用空格、括号和分号作为分隔符。
Extract Data from a line之前的问题我已经回答了
我在下面解释了该代码:
#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
【讨论】:
有很多不同的方法可以做到这一点。例如,您可以使用<regex> 并选择它们,但我认为从字符串流中提取会更容易。
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;
}
代码取自这里:Extract integers from string
【讨论】:
如果您想从包含任何内容的字符串中提取它们(您不知道其他字符是什么),您可以使用 stringstream
例如,假设数字是 int 并希望提取的 int 在 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;
}
编译和执行:
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:~ $
请注意,解决方案“123 a12 13”将产生 123 和 13,而不是 123 12 13。
要从“123 a12 13”生成 123 12 13,只需读取一个字符而不是一个字符串,以防出错:
#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;
}
编译和执行:
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
【讨论】:
一次性解决方案可以扫描字符串以查找从下一个可用数字开始并在非数字字符处停止的范围。然后从范围内的字符创建一个整数并继续直到到达字符串的末尾。
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;
}
例子:
auto v = extract_ints("[1,2,3]");
for (int i=0; i<v.size(); i++)
cout << v[i] << " ";
输出:
1 2 3
【讨论】: