Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Unable to exit while loop

  1. Sep 12, 2008 #1

    Defennder

    User Avatar
    Homework Helper

    I'm writing a c++ program which simulates the behaviour of notepad in this sense. Suppose we input (keyboard) 'high<<<<^^^^11'. Expected outout is '11'

    Here '<' represents pressing left arrow key once, and ^ represents the delete key. '>' represents the right arrow key. To achieve this I made use of a doubly-linked list, whose implementation was done from scratch and is included within the same driver file.

    I've checked the insertion operation and for some reason the program is not able to exit the "while" loop to print the result after processing the input. The "Test" line was included to see if it could exit, but so far it hasn't exited the while loop. I'm wonderin how cin works here.

    Here is the code:
    Code (Text):
    #include <iostream>
    #include <list>

    using namespace std;

    class ListNode {
        private:
            char c;
            ListNode *prev;
            ListNode *next;
        public:
            Default argument for *p and *n is NULL
            ListNode(char character, ListNode *p = NULL, ListNode *n = NULL) : c(character), prev(p), next(n) {}

            // define accessor methods

            ListNode* getprev(){
                return prev;}

            ListNode* getnext(){
                return next; }

            // define mutator methods
            void setprev(ListNode *cur){
                prev = cur;}
            void setnext(ListNode *cur){
                next = cur;}
           
            // method to print the list starting from current node

            void printList() {
                cout<<c;}

            // complete this method
    };

    int main() {
        char curr;  //current character from input
        ListNode *head = NULL;
        ListNode *cursor = NULL;

        while (cin>>curr) {
            switch (curr) {
                case '<' : if(cursor!=head)
                               cursor = cursor->getprev();
                           //this checks that the linked list is not
                           //already at the start before moving
                           break;

                case '>' : if(cursor->getnext()!=NULL)
                               //This checks the list has entries and that
                               //cursor is not already at the end before moving
                               //right
                               cursor = cursor->getnext();
                           break;

                case '^' : if(cursor->getnext()!=NULL){//over here deletion
                               //deletes the node after the one pointed to
                               //by cursor.  Note that the cursor does not
                               //move at all after deletion.
                               ListNode *delnode = cursor->getnext();
                               delnode->getnext()->setprev(cursor);
                               cursor->setnext(delnode->getnext());
                               delete delnode;
                               delnode = NULL;}
                               break;

                default : if(head==NULL){ //This part of the code initialises
                              //the linked list upon input of the first valid
                              // non space character.  When this is executed
                              // the linked list is no longer empty.  The head
                              // is effectively the dummy node since nothing
                              // is stored in it
                              head = new ListNode('\0');
                              ListNode *newPtr = new ListNode(curr,head,NULL);
                              //The head's next ptr now points to the first
                              //valid data node
                              head->setnext(newPtr);
                              //Here cursor points to the first valid entry
                              cursor = newPtr;
                              newPtr = NULL;
                              }
                              else {
                                  //Insertion is done after the node which is
                                  //pointed to by cursor
                                  ListNode *newPtr;
                                  newPtr = new ListNode(curr,cursor,cursor->getnext());
                                  if (cursor->getnext()!=NULL)
                                      //This part assumes that insertion is not done
                                      //at the tail.
                                  { (newPtr->getnext())->setprev(newPtr); }
                                  cursor->setnext(newPtr);
                                  cursor = newPtr;
                                  newPtr = NULL;}
                                  break;
            }
        }
        cout<<"End of while"<<endl;

        //Prints the List
        cout<<"Test"<<endl;
        ListNode *printnode = head->getnext();
        while (printnode!=NULL)
        {   printnode->printList();
            printnode = printnode->getnext();}
            return 0;
    }
    Suppose I enter "12345" as the input. After hitting the enter key, nothing happens as though the program is expecting some more input. How do I make it such that it recognises the return key as a input to terminate the while loop?
     
  2. jcsd
  3. Sep 13, 2008 #2

    mgb_phys

    User Avatar
    Science Advisor
    Homework Helper

    The break statement only breaks out of the inner most loop, in this case the switch statement. The easiest way is to have an extra bool that you set to true if you find the return, and add a test like.

    bool bHaveReturn=false

    while (!bHaveReturn && cin>>curr) {

    // in the case with the return
    bHaveReturn=true;
    }
    You could also use a goto ;-)
     
  4. Sep 13, 2008 #3

    Borek

    User Avatar

    Staff: Mentor

    Learn how to use exceptions.

    Code (Text):

    void some_function()
    {
      if (something went wrong) throw SomeError();
    }

    void function()
    {
      try
      {
    // throw exception - it will be handled by the catch below
        if (something went wrong) throw EndOfWork();

    // blah blah code
        while (1)
        {
    // if you throw exception it will be handled in the same place
          if (we are done) throw EndOfWork();

    // call function - if the exception will be thrown there
    // it will be handled by the catch below as well
          some_function();
        }  
      }

    // it will catch everything, no matter where the exception is thrown
      catch (EndOfWork)
      {
    // do whatever needs to be done
      }
    }
     
    You may have different exceptions thrown out from the same piece of code and each will be handled separately.
     
  5. Sep 13, 2008 #4

    Defennder

    User Avatar
    Homework Helper

    Hi, thanks for replying. I think the problem here is that the >> extractor basically ignores white spaces, and that includes newline which is the return key. Goto isn't covered in my course, so I assume it's not needed. Does using exceptions here really help? After if the input newline character is ignored the code won't execute, right? What should I use to make them not ignore the newline char?
     
  6. Sep 13, 2008 #5

    mgb_phys

    User Avatar
    Science Advisor
    Homework Helper

    Goto is considered bad form so probably isn't covered in your course.
    Exceptions are just goto in stylish new clothes - you shouldn't really use them for a normal event like an end of input, only for an 'exceptional' event
     
  7. Sep 13, 2008 #6

    Borek

    User Avatar

    Staff: Mentor

    Matter of style IMHO. You may use additional BOOL variable and test it in every nested loop, but it it makes code hard to read and analyze, in such case throwing exceptions makes code much more readable.

    In the end it all boils down to jumps, whether we like it or not.
     
  8. Sep 14, 2008 #7

    rcgldr

    User Avatar
    Homework Helper

    One of the advantages of an exception or a goto, is that it's a lot easier to search for a label than for a nested right brace when browsing a program without a special editor.
     
  9. Sep 14, 2008 #8

    Defennder

    User Avatar
    Homework Helper

    Well, that's for exceptions, which I don't think I need to use because there is no such thing as an invalid input here. The question is what should I use to make the program recognise the newline character as input to terminate and print the output?
     
  10. Sep 14, 2008 #9

    Borek

    User Avatar

    Staff: Mentor

    Exception doesn't mean "invalid input". It can mean whatever you want. It can mean "I have found newline in the input and I want to terminate the loop".

    You don't have to use exception here, but it fits problem as described.
     
  11. Sep 15, 2008 #10

    Defennder

    User Avatar
    Homework Helper

    I don't see how that answers the question I raised earlier. The problem I have is that cin>>curr does not recognise the newline character at all (I read this from my lecture notes), it ignores it as input, which is why it doesn't exit the while loop. But this part of the code was given as part of a pre-existing skeleton code the course instructors gave me, so I'm assuming I don't have to modify this part to make the program work (ie. exit the while loop to print the output). I've seen some of my other coursemates' code and they didn't appear to modify the that part of the code as well.

    Now what can I use to get this to work?
     
  12. Sep 15, 2008 #11

    Borek

    User Avatar

    Staff: Mentor

    OK, sorry, I thought it is the problem mgb_phys signalled.

    Perhaps use cin.get(curr)?
     
  13. Sep 15, 2008 #12

    Defennder

    User Avatar
    Homework Helper

    Hi, I apologise if I sounded a little impatient earlier. I tried out your suggestion and I think while it does preserves white spaces in the input, it seems to ignore newline character as well. This is from a small test program:
    Code (Text):
    1 #include <iostream>
      2 using namespace std;
      3
      4 int main()
      5 {
      6     char curr;
      7
      8     while(cin.get(curr)) {
      9         if(curr=='LF')
     10             break;
     11         cout<<curr; }
     12        
     13         return 0;
     14 }
    Since I'm meant to do this on a Unix system, I looked up the ACSCII table and found that the character for newline is 'LF'. Compiling gave me an error as follows:

    test.cpp:9:18: warning: multi-character character constant
    test.cpp: In function `int main()':
    test.cpp:9: warning: comparison is always false due to limited range of data type

    And this suggests that C++ doesn't recognise 'LF' as the newline character. Indeed entering '12345' as the input gives me '12345' as the output without terminating the program. No luck here.
     
  14. Sep 15, 2008 #13

    CRGreathouse

    User Avatar
    Science Advisor
    Homework Helper

    An alternative to goto and exceptions would be to put the loops you're trying to exit in a function and use return instead of break/throw.
     
  15. Sep 15, 2008 #14

    mgb_phys

    User Avatar
    Science Advisor
    Homework Helper

    'LF' is the name of the ascii character, the character code is '\n' or 0xa
    it may also return carriage return '\r' or 0xd
     
  16. Sep 15, 2008 #15

    jtbell

    User Avatar

    Staff: Mentor

    Use '\n' instead:

    Code (Text):

    while (cin.get(curr)) {
        if (curr == '\n')
            break;
        cout<<curr; }
     
    Or this, which eliminates the break:

    Code (Text):

    while (cin.get(curr) && (curr != '\n')) {
        cout << curr;  }
     
     
  17. Sep 16, 2008 #16

    Defennder

    User Avatar
    Homework Helper

    Hi guys, I tried it out and it works. So thanks!
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?



Similar Discussions: Unable to exit while loop
  1. C while loop issue (Replies: 26)

  2. Do while loop (Replies: 6)

Loading...