从输入字符串c ++中提取数字

时间:2016-02-06 03:25:37

标签: c++ parsing

我正在尝试解析从公式中读取的一些输入字符串反应公式:2W + B = 8A + 10Z,我对字符不感兴趣我只需要拆分并提取整数值以将它们放入一个载体即与此反应有关的载体是:[2 1 8 10] 我想过很多事情:std::strtok(),isdigital(),find_first_of()但它们都不适用于整数值......任何身体都可以帮助吗?

我的尝试:

int main()
{
  std::string input;
  std::getline(std::cin, input);
  std::stringstream stream(input);
  while(1) {
      int n;
      stream >> n;
      char * pch;
      pch = strtok (input," ");
      while (pch != NULL)
        {
          printf ("%s\n",pch);
          pch = strtok (NULL, " ,.");
        }
  }
}

3 个答案:

答案 0 :(得分:2)

这是另一种解决方案:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
  string equ;
  vector<int> digits;
  cout << "enter your equation: \n";
  cin >> equ;

  for (auto i : equ)
  {
      if (isdigit(i))
        {
          digits.push_back(stoi(string{i}));
      }
  }

  for (auto& i : digits)
  {
      cout << i << endl;
  }

  system("pause");
  return 0;
}

答案 1 :(得分:2)

在这种特殊情况下,这将做你想要的。但是,我建议您查看regex以更好地解析您的等式。您可能需要考虑所有可能的输入案例。其中包括\-*以及您可能希望在等式中添加的其他运算符。另外,我假设你方程中的变量只有一个字符。

int main()
{
  string input;
  getline(std::cin, input);
  stringstream stream(input);

  char tmp[256];
  const char *in = input.c_str();
  char str[256];
  strcpy(str,in);
  int x;
  tmp[0]='\0';
  char c;
  vector<int> vec;
  //Scan for the digit
  //if it is, store the rest of the string back to str
  //if it isn't, store the part of the string before a digit to tmp
  while (sscanf(str,"%d%s",&x,str)  || sscanf(str,"%[^0123456789]%s",tmp,str) > 1)
    {
      //check if tmp has the form [variable name]+[a string]
      //a string can include another variable name and an operator, = in this case
      while(sscanf(tmp,"%c+%[^0123456789]",&c,tmp) > 1)
        vec.push_back(1);
      if (tmp[0]=='\0')
        vec.push_back(x);
      tmp[0]='\0';
    }

  //just in case there're more special cases
  while(sscanf(str,"%c+%[^0123456789]",&c,str) > 1)
    vec.push_back(1);

  for(int i = 0; i < vec.size(); i++)
    cout << vec[i] << endl;
}

输出:

2
1
8
10

请参阅评论以获得解释。

修改

如果您有特殊情况2W+B=8A+10Z+C+D,请务必小心。请注意,最后C D应该都有系数1.这也可能发生在等式的中间。

答案 2 :(得分:0)

你可以简单地做这样的事情,评论见代码

#include <iostream>
#include <string>
#include <vector>

std::vector<int> Split(std::string str)
{
  std::vector<int> result; // will contain the different ints

  // set pointer to first character in the string
  char const* pch = str.c_str();
  std::string digit; // buffer to keep digits if more than one
  int sign = 1; // each number has a sign -1 or 1

  for (; *pch; ++pch)
  {
    if (std::isdigit(*pch))  // if a digit, put in temp buffer
    {
      digit += *pch;
    }
    else if (std::isalpha(*pch)) // if not a digit evaluate the ones we have
    {
      if (digit.empty()) // none so assume 1 before letter e.g. W+2B
      {
        result.push_back(1*sign);
      }
      else 
      {
        result.push_back(stoi(digit)*sign);
        digit = "";
      }
    }
    else  // determine sign of number
    {
      digit = "";
      if (*pch == '+') 
      {
        sign = 1; 
      }
      else if (*pch == '-') 
      {
        sign = -1;
      }
    }
  }

  return result;
}


int main()
{
  using namespace std;

  string expr{"-2W+B=-8A+10Z"};
  auto digits = Split(expr);
  for (auto& digit : digits)
  {
    cout << digit << endl;
  }


  return 0;
}