c++loopswhile-loop

c++ why doesn't the while loop actually loop?


I'm writing a program that tracks books you've read, want to read, or didn't finish. When I first run the program, I add a new book, then view a list, then try to add a new book again but it gets stuck asking the same thing (would you like to: a:add new book, b:view list, :exit) no matter how any times I enter "a". The same thing happens when I try to view a list if I've already viewed a list once before. I've been at it for hours so sorry if it's obvious but what am I doing wrong, what do I change? This is what I have so far:

string AddNewBook() {
    string title;
    string author;
    string titleandauthor;
    
    cout << "\nWhat is the title of the book?\n   " ;
    getline(cin, title);
    
    cout << "\nWho is the author?\n   " ;
    getline(cin, author);
    
    titleandauthor = title + " by " + author;
        
    return titleandauthor;
}

int main() {
    string q1;
    string title;
    string author;
    string q2;
    string book;
    string addbookq = "y";
    vector<string> booksread;
    vector<string> tbr;
    vector<string> dnf;
    string seelistq;
    int readnument;
    int tbrnument;
    int dnfnument;
    int i;
    string seeanotherlistq = "y";
    
    cout << "Welcome to the Book Tracker!\n" << endl;
    
    cout << "Would you like to:\n   A: Add a new book\n   B: View a list\n   C: Exit" << endl;
    cout << "Enter letter: " ;
    cin >> q1;
    cin.ignore();
    while (q1 == "a" or q1 == "A" or q1 == "b" or q1 == "B") {
        if (q1 == "A" or q1 == "a") {
            while (addbookq == "Y" or addbookq == "y" or addbookq == "Yes" or addbookq == "yes") {
                book = AddNewBook();
                cout << "\nWould you like to:\n   A: Add this book to the Read list\n   B: Add this book to the To Be Read list\n   C: Add this book to the Did Not Finish list" << endl;
                cout << "Enter letter: " ;
                getline(cin, q2);
                while (q2 != "A" && q2 != "a" && q2 != "B" && q2 != "b" && q2 != "C" && q2 != "c") {
                    cout << "\nInvalid entry, please try again: " ;
                    getline(cin, q2);
                }
                if (q2 == "A" or q2 == "a") {
                    booksread.push_back(book);
                    cout << "Added to Read list." << endl;
                }
                else if (q2 == "B" or q2 == "b") {
                    tbr.push_back(book);
                    cout << "Added to the To Be Read List." << endl;
                }
                else if (q2 == "C" or q2 == "c") {
                    dnf.push_back(book);
                    cout << "Added to the Did Not Finish List." << endl;
                }
                cout << "\nAdd another book? " ;
                getline(cin, addbookq);
            }
        }
        else if (q1 == "B" or q1 == "b") {
            while (seeanotherlistq == "Y" or seeanotherlistq == "y" or seeanotherlistq == "Yes" or seeanotherlistq == "yes") {
                cout << "\nWhich list would you like to see:\n   A: Read list\n   B: To Be Read list\n   C: Did Not Finish list" << endl;
                cout << "Enter letter: " ;
                getline(cin, seelistq);
                if (seelistq == "a" or seelistq == "A") {
                    if (booksread.size() == 0) {
                        cout << "\nThere are no books in the Read List yet." << endl;
                    }
                    else if (booksread.size() == 1) {
                        cout << "\nThere is 1 book in the Read list: " << booksread.at(0) << endl;
                    }
                    else {
                        cout << "\nThere are " << booksread.size() << " books in the Read list. How many titles would you to see?" << endl;
                        cin >> readnument;
                        cout << endl;
                        for (i = 0; i < readnument; i++) {
                            cout << i + 1 << ". " << booksread.at(i) << endl;
                        }
                    }
                }
                else if (seelistq == "b" or seelistq == "B") {
                    if (tbr.size() == 0) {
                        cout << "\nThere are no books in the To Be Read list yet." << endl;
                    }
                    else if (tbr.size() == 1) {
                    cout << "\nThere is 1 book in the To Be Read list: " << tbr.at(0) << endl;
                    }
                    else {
                        cout << "\nThere are " << tbr.size() << " books in the To Be Read list. How many titles would you like to see?" << endl;
                        cin >> tbrnument;
                        cout << endl;
                        for (i = 0; i < tbrnument; i++) {
                            cout << i + 1 << ". " << tbr.at(i) << endl;
                        }
                    }
                }
                else if (seelistq == "c" or seelistq == "C") {
                    if (dnf.size() == 0) {
                        cout << "\nThere are no books in the To Be Read list yet." << endl;
                    }
                    else {
                        cout << "\nThere are " << dnf.size() << " books in the Did Not Finish list. How many titles would you like to see?" << endl;
                        cin >> dnfnument;
                        for (i = 0; i < dnfnument; i++) {
                            cout << i + 1 << ". " << dnf.at(i) << endl;
                        }
                    }
                }
                cout << endl;
                cout << "See another list? " ;
                getline(cin, seeanotherlistq);
            }
        }
        cout << "\nWould you like to:\n   A: Add a new book\n   B: View a list\n   C: Exit" << endl;
        cout << "Enter letter: " ;
        cin >> q1;
        cin.ignore();
    }

    cout << "\nThank you for using the Book Tracker!" << endl;
    
    return 0;
}

here's a sample output:

Welcome to the Book Tracker!

Would you like to:
   A: Add a new book
   B: View a list
   C: Exit
Enter letter: a

What is the title of the book?
   dark disciple

Who is the author?
   christie golden

Would you like to:
   A: Add this book to the Read list
   B: Add this book to the To Be Read list
   C: Add this book to the Did Not Finish list
Enter letter: b
Added to the To Be Read List.

Add another book? n

Would you like to:
   A: Add a new book
   B: View a list
   C: Exit
Enter letter: b

Which list would you like to see:
   A: Read list
   B: To Be Read list
   C: Did Not Finish list
Enter letter: b

There is 1 book in the To Be Read list: dark disciple by christie golden

See another list? n

Would you like to:
   A: Add a new book
   B: View a list
   C: Exit
Enter letter: a

Would you like to:
   A: Add a new book
   B: View a list
   C: Exit
Enter letter: b

Would you like to:
   A: Add a new book
   B: View a list
   C: Exit
Enter letter: c

Thank you for using the Book Tracker!
 

Solution

  • After you choose A or B in the main loop, and the next while loop finishes its work, you are not reseting your addbookq/seeanotherlistq variable which terminated that loop, so the next time you reach that same loop again, it has no work to perform, so you just go back to the main loop.

    To fix this, you need to either:

    • reset your variables each time, eg:

      while (addbookq == "Y" or addbookq == "y" or addbookq == "Yes" or addbookq == "yes") {
          ...
          getline(cin, addbookq);
      }
      addbookq = "Y"; // <-- add this
      

      Or

      addbookq = "Y"; // <-- add this
      while (addbookq == "Y" or addbookq == "y" or addbookq == "Yes" or addbookq == "yes") {
          ...
          getline(cin, addbookq);
      }
      
    • use do..while loops, eg:

      do {
          ...
          getline(cin, addbookq);
      }
      while (addbookq == "Y" or addbookq == "y" or addbookq == "Yes" or addbookq == "yes");