1

This program is supposed to check whether the parentheses are balanced (open and closing). The program runs, but returns valid for all user input.

#ifndef _STACKLSAB_H_
#define _STACKSLAB_H_

#include <stack>
#include <string>
#include <vector>
#include "namevaluepair.h"

using namespace std;

class Stacks
{
  public:
    bool balanced(string exp);
    bool match(char open, char closed);
           
  private:
    string st_PostData;
};

#endif

stacksLab.cpp (my program works in repl.it but doesn't with cgi):

#include <iostream>
#include <sstream>
#include "stacksLab.h"
#include <stack>

using namespace std;

bool Stacks::match(char open,char closed)
{
    if(open == '(' && closed == ')') return true;
    else if(open == '{' && closed == '}') return true;
    else if(open == '[' && closed == ']') return true;
    return false;
}
bool Stacks::balanced(string exp)
{
    stack<char>  S;

    for(int i = 0;i<exp.length();i++)
    {
        if(exp[i] == '(' || exp[i] == '{' || exp[i] == '[')
            S.push(exp[i]);
        else if(exp[i] == ')' || exp[i] == '}' || exp[i] == ']')
        {
            if(S.empty() || !match(S.top(),exp[i]))
                return false;
            else
                S.pop();
        }
    }
    return S.empty();
}

main.cpp

#include <iostream>
#include "stacksLab.h"

#include <stack>

using namespace std;

int main()
{
  /// complete the http header
  cout << "Content-type: text/html\n\n";

  Stacks st;

  string expression;
  cin>>expression;

   if(st.balanced(expression))
        cout<<"Valid\n";
    else
        cout<<"Not Valid\n";

}

I think this is the reason my program will not return correctly but not sure which way to go.

<form action="runme.cgi" method="POST">

<table align="center" bgcolor="antiquewhite">

<tr>
   <td align="right">Enter parentheses here:</td>
   <td><input type="text" name="parentheses "/> </td>
</tr>

<tr>
    <td align="right"><input type="submit" /></td>
</tr>

</table>
</form>
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Cheryl
  • 39
  • 3
  • Unrelated to the question, but you should read this: https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice – AVH Oct 19 '20 at 14:15
  • 2
    Debugging, step one: echo the input in order to verify that it is what you believe it to be. – molbdnilo Oct 19 '20 at 14:18
  • 1
    Which inputs are giving you "Valid" that should be "Not valid"? – NotAProgrammer Oct 19 '20 at 14:26
  • Also technically identifiers that start with an underscore followed by a capital letter "such as `#ifndef _STACKLSAB_H_` are reserved for the implementation. Unlikely to cause an issue here but generally it is not a good idea to have a potential clash. – NotAProgrammer Oct 19 '20 at 14:34
  • What is contained in `namevaluepair.h` which you did include but didn't provide in the answer? If it's not relevant, then you should reduce the question to the minimum necessary. – luigi Oct 19 '20 at 14:34
  • Every input I enter it is giving me a "Valid" response. It should only say "Valid if the parenthesis match. like '(' and ')' but it is giving a "valid" response for just a single '(' and that should response should be "Not valid" – Cheryl Oct 19 '20 at 14:35
  • Again, echo your input. Add `cout << "Input: " << expression << '\n';` immediately after reading it. – molbdnilo Oct 19 '20 at 14:41

1 Answers1

2

The problem lies not with your stack processing (I gave your code some rudimentary tests, and it seems to work) but, rather, with the way your are taking input.

The cin << expression; line will read characters from your input up to but not including the first whitespace (i.e. a newline or a space character). Thus, if you enter the string, abc (((}}} (which, clearly, has unbalanced brackets), then your program will show valid because the string it is testing is just the abc part.

To fix this, use the std::getline function, instead, which reads up to the first occurrence of a given delimiter character (which, by default, is the newline).

The following main works with the rest of your code unchanged, judging from the (admittedly, limited) tests I have run:

int main()
{
    cout << "Content-type: text/html\n\n";
    Stacks st;
    string expression;
    getline(cin, expression, '\n'); // The '\n' argument can be omitted, as this is the default

    if (st.balanced(expression))
        cout << "Valid\n";
    else
        cout << "Not Valid\n";

    return 0;
}

As an additional 'suggested improvement', you should perhaps change the int i loop-index in your balanced function to a size_t type - which is actually the type required for operands to the [] operator of Standard Library container objects (like std::string and std::vector):

bool Stacks::balanced(string exp)
{
    stack<char>  S;
    for (size_t i = 0; i < exp.length(); i++) { // size_t is more precise than int
        //... and so forth
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • given the input appears to be html, he may also want to just read the entire stream into `expression`, but I don't know an easy way to do that – Mooing Duck Oct 19 '20 at 16:40
  • @MooingDuck If that's the case (I'll await clarity from OP) then we could just set `expression` empty and, in a `while` loop keep reading into another string and concatenating that to `expression` until the stream is depleted. – Adrian Mole Oct 19 '20 at 16:47