2

The title is self explanatory. For some reason in the loop in int main(), if the user wants to input another book, the loop skips the input of the first function and goes straight to asking for the author's name. For example:

Title: The Lord of the Rings

Author: J.R.R. Tolkien

Copyright: 1954

Enter ISBN numbered separated by spaces: 1 2 3 x

Checked out?(Y or N): Y

Are you finished?(Y or N): N // this starts loop over, Y will issue a break

Title: // there is actually no space between this line and the next, which there should be

Author: // it skips down to this line, not allowing the user to input the title, this cycle continues if the user continues inputting information - always skipping the input for title

Code:

#include "std_lib_facilities.h"

class Book{
public:
       vector<Book> books; // stores book information
       Book() {}; // constructor
       string what_title();
       string what_author();
       int what_copyright();
       void store_ISBN();
       void is_checkout();
private:
        char check;
        int ISBNfirst, ISBNsecond, ISBNthird;
        char ISBNlast;
        string title;
        string author;
        int copyright;
};

string Book::what_title()
{
       cout << "Title: ";
       getline(cin,title);
       cout << endl;
       return title;
}

string Book::what_author()
{
       cout << "Author: ";
       getline(cin,author);
       cout << endl;
       return author;
}

int Book::what_copyright()
{
    cout << "Copyright Year: ";
    cin >> copyright;
    cout << endl;
    return copyright;
}

void Book::store_ISBN()
{
     bool test = false;
     cout << "Enter ISBN number separated by spaces: ";
     while(!test){
     cin >> ISBNfirst >> ISBNsecond >> ISBNthird >> ISBNlast;
     if((ISBNfirst<0 || ISBNfirst>9) || (ISBNsecond<0 || ISBNsecond>9) || (ISBNthird<0 || ISBNthird>9))
                   error("Invalid entry.");
     else if(!isdigit(ISBNlast) && !isalpha(ISBNlast))
          error("Invalid entry.");
     else test = true;}     
     cout << endl;
}

void Book::is_checkout()
{
     bool test = false;
     cout << "Checked out?(Y or N): ";
     while(!test){
     cin >> check;
     if(check == 'Y') test = true;
     else if(check == 'N') test = true;                                
     else error("Invalid value.");}
     cout << endl;
}

int main()
{
    Book store;
    char question = '0';
    while(true){
        store.what_title();
        store.what_author();
        store.what_copyright();
        store.store_ISBN();
        store.is_checkout();
        store.books.push_back(store);
        cout << "Are you finished?(Y or N): ";
        cin >> question;
        if(question == 'Y') break;
        else if(question == 'N') cout << endl;
        else error("Invalid value.");
        }
    cout << endl;
    keep_window_open();
}

The header information can be found here if you're interested in functions like keep_window_open() and error(), but it doesn't really pertain to this issue. - http://www.stroustrup.com/Programming/std_lib_facilities.h

Any help would be appreciated - thanks.

trikker
  • 2,651
  • 10
  • 41
  • 57

3 Answers3

5

The following line:

cin >> question;

reads in the 'Y' or the 'N' character. When you enter the input, you also type a 'return' or 'enter'. That return/enter is still in the buffer. When you get to getline(cin,title); the second time through the loop, that return/enter that is still in the buffer is read in and interpreted as the entire line.

What you need to do is either clear the input buffer with cin.flush(); or you need to read in question as a string and not as a character.

Here is what your code should look like

int main()
{
    Book store;
    char question = '0';
    while(true){
        store.what_title();
        store.what_author();
        store.what_copyright();
        store.store_ISBN();
        store.is_checkout();
        store.books.push_back(store);
        cout << "Are you finished?(Y or N): ";
        cin >> question;
        if(question == 'Y') break;
        else if(question == 'N')
        {
            cout << endl;
            cin.flush();
        }
        else error("Invalid value.");
        }
    cout << endl;
    keep_window_open();
}
epotter
  • 7,631
  • 7
  • 63
  • 88
  • Reading question as a string doesn't work, but I tried cin.flush() and istream has no member named flush. Do I need to define it myself or am I missing a header? – trikker Jul 17 '09 at 16:48
  • I tried just using cin.ignore() instead of cin.flush() and it worked. I"ll put this as the answer. – trikker Jul 17 '09 at 16:55
1

Try

  std::cin.ignore(INT_MAX);();

So something like this:

string Book::what_title()
{
       cout << "Title: ";
       std::cin.ignore(INT_MAX);
       getline(cin,title);
       cout << endl;
       return title;
}

If that does not help check out How do I flush the cin buffer?

Reading the full line (using getline) as some of the other answers are indicating should also take care of the rogue EOL character in the input stream.

Edit: Removed cin.flush since that as not as standard as I thought.

Community
  • 1
  • 1
Jesse Vogt
  • 16,229
  • 16
  • 59
  • 72
  • I tried cin.flush and it isn't recognized. I also tried cin.ignore(INT_MAX) which just leaves the program hanging. – trikker Jul 17 '09 at 16:49
1

do you hit enter while answering

    Are you finished?(Y or N):

can you replace

cin >> question;

with

getline(cin,question);

?

A.Rashad
  • 1,066
  • 12
  • 26