我有一个"blah-blah..obj_xx..blah-blah"
形式的字符串,其中xx
是数字。例如。字符串可能是"root75/obj_43.dat"
。
我想将"xx"
(或上面示例中的43
)作为整数阅读。我该怎么做?
我试图找到" obj _"第一:
std::string::size_type const cpos = name.find("obj_");
assert(std::string::npos != cpos);
但下一步是什么?
答案 0 :(得分:2)
我的GCC并不完全支持正则表达式,但我认为这应该有效:
#include <iostream>
#include <string>
#include <regex>
#include <iterator>
int main ()
{
std::string input ("blah-blah..obj_42..blah-blah");
std::regex expr ("obj_([0-9]+)");
std::sregex_iterator i = std::sregex_iterator(input.begin(), input.end(), expr);
std::smatch match = *i;
int number = std::stoi(match.str());
std::cout << number << '\n';
}
答案 1 :(得分:1)
有了这么简单的事情,你可以做到
auto b = name.find_first_of("0123456789", cpos);
auto e = name.find_first_not_of("0123456789", b);
if (b != std::string::npos)
{
auto digits = name.substr(b, e);
int n = std::stoi(digits);
}
else
{
// Error handling
}
对于任何更复杂的事情,我都会使用正则表达式。
答案 2 :(得分:0)
怎么样:
#include <iostream>
#include <string>
int main()
{
const std::string test("root75/obj_43.dat");
int number;
// validate input:
const auto index = test.find("obj_");
if(index != std::string::npos)
{
number = std::stoi(test.substr(index+4));
std::cout << "number: " << number << ".\n";
}
else
std::cout << "Input validation failed.\n";
}
Live demo here。包括(非常)基本输入验证(例如,如果字符串包含多个obj_
,它将失败),最后可变长度数字,或者跟随它的更多内容(相应地调整substr
调用)和你可以向std::stoi
添加第二个参数,以确保它不会因某种原因而失败。
答案 3 :(得分:0)
这是另一个选择
//your code:
std::string::size_type const cpos = name.find("obj_");
assert(std::string::npos != cpos);
//my code starts here:
int n;
std::stringstream sin(name.substr(cpos+4));
sin>>n;
答案 4 :(得分:0)
污垢简单的方法,虽然可能效率很低,并且没有利用STL:
(请注意,我没有尝试编译)
unsigned GetFileNumber(std::string &s)
{
const std::string extension = ".dat";
/// get starting position - first character to the left of the file extension
/// in a real implementation, you'd want to verify that the string actually contains
/// the correct extension.
int i = (int)(s.size() - extension.size() - 1);
unsigned sum = 0;
int tensMultiplier = 1;
while (i >= 0)
{
/// get the integer value of this digit - subtract (int)'0' rather than
/// using the ASCII code of `0` directly for clarity. Optimizer converts
/// it to a literal immediate at compile time, anyway.
int digit = s[i] - (int)'0';
/// if this is a valid numeric character
if (digit >= 0 && digit <= 9)
{
/// add the digit's value, adjusted for it's place within the numeric
/// substring, to the accumulator
sum += digit * tensMultiplier;
/// set the tens place multiplier for the next digit to the left.
tensMultiplier *= 10;
}
else
{
break;
}
i--;
}
return sum;
}
如果您需要它作为字符串,只需将找到的数字附加到结果字符串,而不是在sum
中累积它们的值。
这也假定.dat
是字符串的最后一部分。如果没有,我会从最后开始,向左计数,直到找到一个数字字符,然后开始上面的循环。这很好,因为它是O(n)
,但可能不如正则表达式或查找方法一样清晰。