Need string splitting advice

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




@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?
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.