Thread: Problem with Program to Check if Separators Match

  1. #16
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So your main problem seems to be your inability to distinguish between singular and plural.
    Singular = 'single quotes' = char
    Plural = "double quotes" = string

    You must pick one. You cannot, as you attempt to do on line 23, assign a single character to a string. You cannot compare a string to a character. You cannot mix and match between them.

    And your pop function must still return the top element from the stack, not just remove it from the stack and throw it away.

  2. #17
    Registered User
    Join Date
    Sep 2009
    Posts
    78
    Quote Originally Posted by tabstop View Post
    So your main problem seems to be your inability to distinguish between singular and plural.
    Singular = 'single quotes' = char
    Plural = "double quotes" = string

    You must pick one. You cannot, as you attempt to do on line 23, assign a single character to a string. You cannot compare a string to a character. You cannot mix and match between them.

    And your pop function must still return the top element from the stack, not just remove it from the stack and throw it away.
    Okay, that makes sense, but it also confuses me. How am I supposed to do this if I can't assign the value of lineToCheck[j] to a string? Is there a way to convert it from a character to a string? Otherwise, I don't know how to get everything to work together correctly, because I have to get the value of lineToCheck[j] in order to compare it to stuff.

    Also, should I have written my own pop function? I thought pop and push were provided by implementing the stack format. I'm sorry if I'm wrong, but that is what I honestly thought, and I didn't realize I was supposed to write my own pop function. If so, I can do that, but I just thought those functions were provided already.

    I'm so sorry for being so bad at this! I am trying to learn. Thanks for all of your help, tabstop!! :-)

  3. #18
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Oh. For some reason I thought you had your own home-grown stack that you were using. (Was that your last assignment or do I have you confused with a different poster?)

    Anyway, if you're using the standard stack, then you need to top+pop (I don't know why they made that specific design choice, but there you go) -- top gives you the top element, and pop removes it. (Obviously there are good reasons for that design choice, I just don't like it.)

    If you want just a piece of a larger string, then you need to use the substring function substr.

    Just looking at this code, I have no idea what all goes on the stack. If the only thing that goes on the stack are punctuation marks, then those are all singular, so you should have a stack<char> and go from there. (And you use == on chars too, not strcmp.)

  4. #19
    Registered User
    Join Date
    Sep 2009
    Posts
    78
    I think you've got me confused with someone else. No biggie, though! I was just confused as to how I could have completely broken the pop function, and I'm glad to know I didn't totally screw something up in my compiler, heh heh.

    Yeah, the only thing that I am putting on the stack at the punctuation marks, so I will go with char's. I changed everything back to char, and I used == to compare things, and that all seems to work fine now. I am only getting two errors now, and I really have no idea what they mean, unless they still mean that I am not concatenating correctly. The errors are as follows:

    MatchChecker.h|21|warning: comparison between signed and unsigned integer expressions|
    MatchChecker.h|42|error: invalid operands of types `const char*' and `const char[18]' to binary `operator+'|
    MatchChecker.h|48|error: invalid operands of types `const char*' and `const char[18]' to binary `operator+'|

    And here is my updated code:

    Code:
    #include <stdio.h>
    #include <sstream>
    #include <string>
    #include <stdexcept>
    #include <stack>
    
    // protections
    #ifndef MatchChecker_H
    #define MatchChecker_H
    
    using namespace std;
    
    class MatchChecker
    {
    
          public:
          static string matchChecker(string lineToCheck)
          {
                 stack<char> myStack;
    
                 for (int j = 0; j < lineToCheck.length(); j++) // line 20
                 {
                     char ch = lineToCheck[j];
                     switch (ch)
                     {
                            case '{':
                            case '[':
                            case '(':
                                 myStack.push(ch);
                                 break;
                            case '}':
                            case ']':
                            case ')':
                                 if (!myStack.empty())
                                 {
                                    char popper = myStack.top();
                                    myStack.pop();
    
                                     //if (((strcmp (ch, '{') == 0) && (strcmp (popper, '}') == 0)) || ((strcmp (ch, '[') == 0) && (strcmp (popper, ']') == 0)) || ((strcmp (ch, '(') == 0) && (strcmp (popper, ')') == 0)))
                                     if (((ch == '}') && popper == '{') || ((ch == ']') && (popper == '[')) || ((ch == ')') && (popper == '(')))
                                        {
                                        string returnValue = "Error: " + ch + " at the position " + j + " does not match";
                                        return returnValue;
                                        }
                                 }
                                 else
                                 {
                                     string returnValue = "Error: " + ch + " at the position " + j + " does not match";
                                     return returnValue;
                                 }
                                 break;
                            default:
                                 break;
                     }
                 }
                 if (!myStack.empty())
                 {
                 return ("Error: missing right delimiter");
                 }
          }
    };
    
    #endif

  5. #20
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Now we're back to mixing chars and strings again. The usual sort of string builder type thing would be something like
    Code:
    stringstream returnString;
    returnString << "Error: " << ch << " at the position " << j << " does not match";
    returnValue = returnString.str();
    Also you may want to look into returning something in case of success, otherwise you will return a random string.

  6. #21
    Registered User
    Join Date
    Sep 2009
    Posts
    78
    Oh, okay. That works...everything compiles and works fine now. The problem is, now the output is not correct. When I enter a mismatched string, no error message prints out. It just prints the main prompt for the user to choose a new option.

    Also, I am unsure where to put a message for success. I would think it would be in the switch statement, under the case for }, but I don't know how to do that since there is already an else statement there. I don't know what to make the if part of that else statement to make it do what I need it to. Does that make sense? Basically, I just don't know where to put the message.

    Thanks, tabstop! You are so amazing!

  7. #22
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    As to where the put the message, you need to determine where the code gets to when you have a correct string. That's where you put your return. (Notice that it can't possibly be in the switch statement since you can't tell, while you are still switching, that you have a correct string. Only when you have successfully matched all the characters can you tell.)

    You return the error message to main, but main throws it away and doesn't print it. (Or at least the main I see at the top of the thread throws it away and doesn't print it.)

  8. #23
    Registered User
    Join Date
    Sep 2009
    Posts
    78
    Okay...so I have tried to think it through, and I think that I should put it right after the switch statement, before the last if statement. Is that right? What I mean is shown below in my code.

    And, I changed my code so that the returnValues are printed using cout, but I still am not getting anything printed out. Did I not change the right thing to get it to print out?

    Also, I am getting one error now when I try to compile, so I am not thinking that I did the statement for success correctly. The error is this:

    MatchChecker.h|64|error: cannot resolve overloaded function `top' based on conversion to type `char'|

    And here is my code:

    Code:
    #include <stdio.h>
    #include <sstream>
    #include <string>
    #include <stdexcept>
    #include <stack>
    
    // protections
    #ifndef MatchChecker_H
    #define MatchChecker_H
    
    using namespace std;
    
    class MatchChecker
    {
    
          public:
          static string matchChecker(string lineToCheck)
          {
                 stack<char> myStack;
    
                 for (int j = 0; j < lineToCheck.length(); j++)
                 {
                     char ch = lineToCheck[j];
                     switch (ch)
                     {
                            case '{':
                            case '[':
                            case '(':
                                 myStack.push(ch);
                                 break;
                            case '}':
                            case ']':
                            case ')':
                                 if (!myStack.empty())
                                 {
                                    char popper = myStack.top();
                                    myStack.pop();
    
                                    if (((ch == '{') && popper != '}') || ((ch == '[') && (popper != ']')) || ((ch == '(') && (popper != ')')))
                                    {
                                        stringstream returnString;
                                        string returnValue;
                                        returnString << "Error: " << ch << " at the position " << j << " does not match";
                                        returnValue = returnString.str();
                                        cout << returnString;
                                        return returnValue;
                                    }
                                 }
                                 else
                                 {
                                    stringstream returnString;
                                    string returnValue;
                                    returnString << "Error: " << ch << " at the position " << j << " does not match";
                                    returnValue = returnString.str();
                                    cout << returnString;
                                    return returnValue;
    
                                 }
                                 break;
                            default:
                                 break;
                     }
    
                     char popper = myStack.top;  // ERROR HERE
                     if (((ch == '{') && popper == '}') || ((ch == '[') && (popper == ']')) || ((ch == '(') && (popper == ')')))
                     {
                         cout << "Everything is matched!" << endl;
                     }
                 }
                 if (!myStack.empty())
                 {
                 return ("Error: missing right delimiter");
                 }
          }
    };
    
    #endif

  9. #24
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Function calls require (parentheses).

    You shouldn't have any cout in this function.

    And I doubt that's where your line-is-correct code goes, especially since if the line is correct, calling top() will fail horribly (since the stack is empty). (EDIT: That is to say: if you haven't checked for all the errors yet, you can't say that you're okay. Since at that point you haven't checked for all the errors yet, you can't say that you're okay.)

  10. #25
    Registered User
    Join Date
    Sep 2009
    Posts
    78
    Oops, I totally forgot those parentheses. Okay, they are in there now, even though that line won't be staying long, I don't think.

    Okay, if I don't have a cout in here, how do I print the result? Do I change something in my main function? The thing is, that main function was provided to me as part of the assignment, and I'm not supposed to change it. I can find out if that is correct, but I don't think I'm allowed to change the main function.

    Alright...I am really confused about where to put it. Let me run through the pseudo-code one time:

    Code:
    1. create stack of char's named myStack
    2. for loop for while j is less than the length of lineToCheck
    
    a) create a char equal to the value of lineToCheck at index=j b) switch on that char
    * If that char is equal to an opening mark ( {, [, or ( ) push it onto the stack and break * If that char is equal to a closing mark ( }, ], or ) ) do the following:
    -> if the stack is not empty, do the following:
    1) create a char equal to the top of the stack, and pop it 2) if ch is an opening bracket (or brace or parenthesis) and popper is not a closing bracket (or brace or parenthesis), then return the error message
    -> else if the stack IS empty, then return the error message
    * Now break from the switch
    c) End the for loop
    3. if the stack is not empty at the end, return an error message
    I don't know where in that, except inside the switch statement, that I could put a success statement. Maybe at the end, after 3., but then I don't know how to access popper, because I tried and it wouldn't let me. Is that the right place? Or am I still not getting it right?

  11. #26
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Code:
    1. create stack of char's named myStack
    2. for loop for while j is less than the length of lineToCheck
    
        a) create a char equal to the value of lineToCheck at index=j b) switch on that char
    
            * If that char is equal to an opening mark ( {, [, or ( ) push it onto the stack and break * If that char is equal to a closing mark ( }, ], or ) ) do the following:
    
                -> if the stack is not empty, do the following:
    
                    1) create a char equal to the top of the stack, and pop it 2) if ch is an opening bracket (or brace or parenthesis) and popper is not a closing bracket (or brace or parenthesis), then return the error message
    
                -> else if the stack IS empty, then return the error message
    
            * Now break from the switch
    
        c) End the for loop
    
    3. if the stack is not empty at the end, return an error message
    
    4. Now that we've checked everything, if everything came out, then success
    If you're not going to use the return value, then you shouldn't be returning things -- so either you want a void function and do the printing in the function, or you return the string and do the printing in main.

  12. #27
    Registered User
    Join Date
    Sep 2009
    Posts
    78

    `

    Quote Originally Posted by tabstop View Post
    If you're not going to use the return value, then you shouldn't be returning things -- so either you want a void function and do the printing in the function, or you return the string and do the printing in main.
    Yeah, that makes sense, but I am unsure how I am supposed to do it. See, my teacher provided both the main function and the header of the MatchChecker function, so I am thinking that one of the things that was provided to be will have to be changed. I will ask her in class on Monday and see what she says, or maybe send an email about it to get a faster response.

    As to the other issue, where to put the success statement, I am still confused. I understand where I should put it (at the end of everything, after the for loop) but I am unsure how to do it. Do I need to recheck and see if ch is an opening mark and popper is a matching closing mark? Or is it good enough to know that it hasn't terminated elsewhere and just print the success statement? I think its the latter, and that I can just return the success statement, but I am unsure.

    Thank you for the help, tabstop!! I so greatly appreciate all of your time spent helping me!

  13. #28
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you get to the end, there is nothing left to check.

  14. #29
    Registered User
    Join Date
    Sep 2009
    Posts
    78
    Okay. And I emailed my teacher, and she said there was a typo, so that is good. The function should be void, and should print the strings. So I changed that, and it is working fine now.

    I have one more question, and I believe it should be the last! Instead of printing "Error: Missing right delimiter" the program should be printing the exact character that is missing. For instance, if there was an opening parenthesis but not a closing one, the program should print ") is missing." Since I am outside of the for loop now, how do I do this? How do I know which character it is that is making the stack uneven? Do I need to pop it and then compare it to the opening characters and see which one it is?

  15. #30
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    That's exactly what you want to do.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with my program i cant figure out...
    By youareafever in forum C Programming
    Replies: 7
    Last Post: 11-01-2008, 11:56 PM
  2. I have finished my program, one problem
    By sloopy in forum C Programming
    Replies: 4
    Last Post: 11-29-2005, 02:10 AM
  3. Program problem
    By Birdhaus in forum C++ Programming
    Replies: 6
    Last Post: 11-21-2005, 10:37 PM
  4. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  5. Console Program Problem
    By Breach23 in forum C++ Programming
    Replies: 3
    Last Post: 10-19-2001, 12:35 AM