读取字符串中的整数

时间:2014-09-24 12:10:53

标签: c++ c++11

我有一个"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);

但下一步是什么?

5 个答案:

答案 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),但可能不如正则表达式或查找方法一样清晰。