what's wrong with this program?

My main program ends abruptly when this function is in it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void provideHelpIfNecessary(void)
{
    char answer;
    cout <<"Do you need help (Y/N)? :";
    cin >> answer;
    if (isValidResponse(answer) == false) {
        cout << "Invalid response! Try again.\n" << endl;
        provideHelpIfNecessary();
    }
    else if (isValidResponse(answer) == true) {
        if (isYesResponse(answer) == true) {
            cout << "Enter an infix expression at the prompt.\nThe program will\
 tell you its value.\nTo stop the program, just hit 'return' at the prompt.";
        }
        else return; }

} 


and this is the snippet of code in main():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main(void)
//
//
...
//
{
    while(true){
    provideHelpIfNecessary();
    cout << "Expression? ";
    string expr;                    // holds the supposed expression
    getline(cin,expr);
    if (expr.length() == 0)
        break;
//
//
...
// 


with provideHelpIfNecessary() in there, the program stops right after outputting "Expression? ", and without it in there, it runs fine.
anyone see something wrong that I should fix?
Try getline(cin >> ws, expr); instead of getline(cin, expr); and see how that goes.
I'm not allowed to change anything in main(). Pre-written by my professor.

But I tried your suggestion anyways just to check it out, and it seems to brings the program back to the beginning after solving every expression, which is not supposed to happen. It's supposed to go only as far back up as "Expression? "
What parts are you allowed to modify?

The closest simple alternative to the cin >> ws trick is this:
4
5
6
7
cout <<"Do you need help (Y/N)? :";
cin >> answer;
cin.ignore(); // Alternatively, 'cin.ignore(numeric_limits<streamsize>::max(), '\n');'
              // if you can #include <limits> 
but that doesn't fix the other problem (which I'm not sure I understand correctly).
Right, that does fix the exiting problem, but not the other.

So the first that should run is provideHelpIfNecessary(). And then the program should output "Expression? " , followed by the user inputting an expression and seeing the result. The program should automatically loop back to outputting "Expression? ", accepting an input, and outputting the result. This is how it should be. But with cin.ignore(), it loops all the back to the beginning of main(). That is the problem.
The cin.ignore(); itself shouldn't be causing any problems.

Can I see a little more of the main function your professor provided?
I just need a better idea of what's going on in there.
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
124
125
126
127
int main(void)
{
    while(true){
        provideHelpIfNecessary();
        cout << "Expression? ";
        string expr;                    // holds the supposed expression
        getline(cin,expr);
        if (expr.length() == 0)
            break;
        try {
            ValueType result = processExpression(expr);
            cout << result << endl;
        } catch (ZeroDivideException ex) {
            cerr << "Attempt to divide by zero!\n";
        } catch (IllegalExprException ex) {
            cerr << "Illegal infix expression!\n";
        }
    }  // end while
    cout << endl;
} // end main

void provideHelpIfNecessary(void)
{
    char answer;
    cout <<"Do you need help (Y/N)? :";
    cin >> answer;
    cin.ignore();
    if (isValidResponse(answer) == false) {
        cout << "Invalid response! Try again.\n" << endl;
        provideHelpIfNecessary();
    }
    else if (isValidResponse(answer) == true) {
        if (isYesResponse(answer) == true) {
            cout << "Enter an infix expression at the prompt.\nThe program will\
 tell you its value.\nTo stop the program, just hit 'return' at the prompt.";
        }
        else return; }

} // end provideHelpIfNecessary

alueType processExpression(const string& expr)
   throw (IllegalExprException, ZeroDivideException)
{
    stack<ValueType> ValStack;
    stack<char> OpStack;
    for (int i = 0; i < expr.length(); i++)
        {
            if (isdigit(expr[i])){
                ValueType num = expr[i] - '0';
                ValStack.push(num);
            }

            if (expr[i] == '(') OpStack.push(expr[i]);

            if (expr[i] == '*'|| expr[i] == '+'||
                expr[i] == '-'|| expr[i] == '/') {

                if(OpStack.empty()) OpStack.push(expr[i]);

                else if (precedence(expr[i]) > precedence(OpStack.top()))
                    OpStack.push(expr[i]);

                else
                    {
                        while (!OpStack.empty() && precedence(expr[i]) <= prece\
dence(OpStack.top())) execute(ValStack,OpStack);
                        OpStack.push(expr[i]);
                    }}
            if (expr[i] == ')') {
                while (OpStack.top() != '(') execute(ValStack,OpStack);
                OpStack.pop();
            }}

    while (!OpStack.empty()) execute(ValStack,OpStack);
    ValueType result = ValStack.top();
    return result;
} // end processExpression

bool isValidResponse(char response)
{
    if (response == 'Y'|| response == 'y'|| response == 'T'|| response == 't'||
        response == '1'|| response == 'N'|| response == 'n'|| response == 'F'||
        response == 'f'|| response == '0') return true;
    else return false;
} // end isValidResponse

bool isYesResponse(char response)
{
    if ( response == 'Y'|| response == 'y'|| response == 'T'||
         response == 't'|| response == '1') return true;
    else return false;
} // end isYesResponse

int precedence(char op)
{
    if (op == '*' || op == '/') op = 3;
    if (op == '+' || op == '-') op = 2;
    if (op == '(') op = 0;
    else op = -1;
    return op;
} // end precedence

void execute(stack<ValueType>& valStack, stack<char>& opStack)
   throw (IllegalExprException, ZeroDivideException)
{
    ValueType result;
    ValueType operand1 = valStack.top();
    valStack.pop();
    ValueType operand2 = valStack.top();
    valStack.pop();
    char op = opStack.top();
    opStack.pop();
    result = doOperation(operand2,op,operand1);
    valStack.push(result);

} // end execute

ValueType doOperation(ValueType operandL, char operation, ValueType operandR)
   throw (IllegalExprException, ZeroDivideException)
{
    ValueType ans;
    if (operation == '*') ans = operandL * operandR;
    if (operation == '/') ans = operandL / operandR;
    if (operation == '+') ans = operandL + operandR;
    if (operation == '-') ans = operandL - operandR;
    return ans;
} // end doOperation 
Are you trying to "skip" the provideHelpIfNecessary function after the first time?

If so, I would do something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void provideHelpIfNecessary(void)
{
    static bool isFirstRun = true;
    if (isFirstRun)
    {
        isFirstRun = false;
        char answer;
        do
        {
            cout <<"Do you need help (Y/N)? :";
            cin >> answer;
            cin.ignore();
            if (isValidResponse(answer) == false) {
                cout << "Invalid response! Try again.\n" << endl;
            }
        } while (!isValidResponse(answer));
        
        if (isYesResponse(answer) == true) {
            cout << "Enter an infix expression at the prompt.\nThe program will\
 tell you its value.\nTo stop the program, just hit 'return' at the prompt.";
        }
    }
}

Last edited on
Yes! It works good now. Thank you!
Topic archived. No new replies allowed.