Need string splitting advice

Jun 23, 2016 at 2:35pm
Write your question here.

Hey guys, I made a simple calculator that takes user input, and does operations and then returns the results. Currently, to do an operation, the user has to enter everything seperated by a space, which is inconvenient. Are there other ways to calculate input without seperating by spaces?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
  #include <iostream>
#include <string>
#include <cstdlib>

void run();
void intro();

int main()
{
	intro();
	run();
	std::cout << "\n\n";
    std::cin.get();
	return EXIT_SUCCESS;
}

void intro()
{
	std::cout << "-----------------------------------------\n";
	std::cout << "[][][][][]    [|]     []         [][][][]\n";
	std::cout << "[]          []   []   []         []      \n";
	std::cout << "[]          [][]][]   []         []      \n";
	std::cout << "[]          []   []   []         []      \n";
	std::cout << "[][][][][]  []   []   [][][][][] [][][][]\n";
	std::cout << "-----------------------------------------\n";
	std::cout << "\nWelcome to Calc v1.0. Type in a problem to solve, with characters seperated by spaces.\nExamples: 6 + 5  or 65 / 77\n\n\n";
}

void run()
{
	double a, b;
	std::string oper;
	while (true)
	{
		std::cout << ">";
		std::cin >> a >> oper >> b;
		if (oper == "+")
		{
			std::cout << (a + b) << "\n";
			continue;
		}
		else if (oper == "-")
		{
			std::cout << (a - b) << "\n";
			continue;
		}
		else if (oper == "*")
		{
			std::cout << (a * b) << "\n";
			continue;
		}
		else if (oper == "/")
		{
			if (b == 0) {
				std::cout << "Error: No division by 0 permitted!\n";
				continue;
			}
			else
			{
				std::cout << (a / b) << "\n";
				continue;
			}
		}
		break;
	}
}
Jun 23, 2016 at 3:51pm
change line 32 to this char oper;

then put single quotes around your operators on lines 37, 42, 47, and 52 like this if (oper == '+')

then you wont need to worry about splitting apart the input or the need for the input to be separated by spaces.
Last edited on Jun 23, 2016 at 3:52pm
Jun 23, 2016 at 4:03pm
closed account (48bpfSEw)
You need an interpreter.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//---------------------------------------------------------------------------
// Example
//---------------------------------------------------------------------------
int main(void) {
  string  strNumber1,
          strOperator,
          strNumber2;

  TReggae Reggea;
  Reggea.str = "12+13=";    // simulated user input

  for (int i=0;i<Reggea.str.length();i++) {
    try {
      Reggea.iPos = i;
      Reggea.boIgnoreBlock = false;

      Reggea.number(strNumber1)
            .word  (strOperator)
            .number(strNumber2)
            .text  ("=");

      wostringstream os;
      if (Reggea.boFound) {
        
        //---------------------------------------------------------------------------
        // here is your turn: calculate the result of strNumber1, strOperator, strNumber2
        ...
        //---------------------------------------------------------------------------
        

        // set i after "=" for next operations e.g. "12+13=-4/3=..."
        i = Reggea.iPos;
        }
      else
        i = Reggea.iPosChecked;
      }
    catch(...) {
      // cxMemo1->Lines->Add("Exception: No match!");
      }
    }
  return 0;
  }



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
   
//---------------------------------------------------------------------------
// Reaggae Header
//---------------------------------------------------------------------------
#include <string>
#include <map>

using namespace std;

class TReggae {
public:
  TReggae();
  TReggae& white  (void);
  TReggae& word   (string& strVar);
  TReggae& text   (string strVar);

  void     next   (int& i);

public:
 int      iPos;
 int      iPosChecked;
 string   str;
 bool     boFound;
};
#endif 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
   
//---------------------------------------------------------------------------
// Reaggae CPP
//---------------------------------------------------------------------------
#include "Reggea.h"
#include <sstream>      // wostringstream

TReggae::TReggae() {
  iPos = 0;
  iPosChecked = 0;
  str  = "";
  boFound = false;
  }

/* Example to ignore a block between { and }
TReggae& TReggae::block (void) {

  if (!boIgnoreBlock)
    return *this;

  if(iPos >= str.length())
    return *this;

  if (str[iPos] != '{')
    return *this;

  iPos++;

  for (;iPos < str.length(); iPos++)
    if (str[iPos] == '}')
      break;

  iPosChecked = iPos;

  return *this;
}
*/

TReggae& TReggae::white (void) {

  for (;iPos < str.length(); iPos++)
    if (!isspace(str[iPos]))
      break;

  boFound = true;
  iPosChecked = iPos;

  // block();

  return *this;
}

TReggae& TReggae::number (string& strVar) {
  
  white();

  strVar = "";
  for (;iPos < str.length(); iPos++) {

    if (!isnum(str[iPos]) && str[iPos] != '_')
      break;

    strVar += str[iPos];
    boFound = true;
    }

  if (strVar.length() == 0)
    throw -1;

  return *this;
}

TReggae& TReggae::word (string& strVar) {

  white();

  strVar = "";
  for (;iPos < str.length(); iPos++) {

    if (!isalnum(str[iPos]) && str[iPos] != '_')
      break;

    strVar += str[iPos];
    boFound = true;
    }

  if (strVar.length() == 0)
    throw -1;

  return *this;
}

TReggae& TReggae::text (string strVar) {

  white();

  if (strVar.length() == 0)    // assert
    throw -2;

  for (int i=0;i<strVar.length(); i++) {
    int iPosTmp = iPos + i;
    if (iPosTmp > str.length())
      throw -3;

    if (strVar[i] != str[iPosTmp])
      throw -4;
    }

  iPos += strVar.length();
  boFound = true;

  iPosChecked = iPos;

  return *this;
}

void TReggae::next (int& i) {

  if (i < iPosChecked)
    i = iPosChecked;
  else
    i++;
  }




Jun 23, 2016 at 9:34pm
@Dirty Dan Thanks for your solution!

@Necip

Im sorry, but being a noob, I really don't understand your code. Could you explain it to me in simple terms, and explain what the interpreter actually is/does?
Jun 24, 2016 at 3:47pm
closed account (48bpfSEw)
Definition of an interpreter is: searching for patterns in a string.

The initialisation part of my HelpClass "Reagea" (it's just a name for my creation!^^) is this part:

1
2
  TReggae Reggea;
  Reggea.str = "12+13=";       // assign the input of the user to Reggea.str 


The main part is that:

1
2
3
4
   Reggea.number(strNumber1)
            .word  (strOperator)
            .number(strNumber2)
            .text  ("=");


first it searches the pattern of a number. if it finds a number it stores the sub-string in the variable strNumber1, then it searches next for a word : in this case it finds "+" and stores that in strOperator and so on. if the last token is a "=" it has found the total sequence of this pattern: <number> <operator> <number> <=>
and now you can be sure that the input was correct and evaluate the result.

Maybe you have to modify the word() function. the pattern is alphanum() instead only alpha() I think...

Try to understand this code, it is simple but powerfull to find any syntax or skip parts in a text... It was a tool I build for my own purposes to analyse DFM-Files in C++ Builder. Any try with regular expressions failed.

You'll see that you need a couble of tools which helps you in coding.
Topic archived. No new replies allowed.