简体   繁体   中英

extracting digits from input string c++

I'm trying to do parsing to some input string reactions read from file at formula :2W+B=8A+10Z, I'm not interested in characters i need only to split and extract the integer values to put them in a vector ie vector associated with the reaction here is :[2 1 8 10] i thought about many things: std::strtok(),isdigital(),find_first_of() but they all didn't work for integer values ... can any body help ??

here my try:

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, " ,.");
        }
  }
}

Here is another solution:

#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;
}

This will do what you want in this particular case. However, i suggest that you look into regex to parse your equation better. You may want to consider all possible cases for your input. This includes \\ , - , * and other operators that you may want to add in your equation. Also, I'm assuming variables in your equation has only one character.

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;
}

Output:

2
1
8
10

See comments for explanation.

EDIT

Be careful when you have a special case 2W+B=8A+10Z+C+D . Notice the last C D should both have coefficients 1. This could happen in the middle of the equation too.

You could simply do something like this, for comments see code

#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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM