0

In my program which is for storing notes, I use std::getline twice to ask the user first for the title of the note, then to ask for the note's body. When running the program, it skips the first getline and goes straight to the second one.

I've tried std::cin, cin.ignore(), cin.sync(), and std::getline of course.

I have three files total. A header and class file, and a main file. For showing what code matters, I'm only showing snippets of the class file and main file where the problem is involved at.

notebook.cpp

// -- snip --

Note Note::create_note() {
  Note s;
  std::string title;
  std::string note;
  std::cout << "\nPlease enter the note's title: \n";
  std::getline(std::cin, title);
  s.set_title(title);
  std::cout << "Please enter the note: ";
  std::getline(std::cin, note);
  s.set_body(note);
  std::cout << "Note added!\n\n";
  return s;
}

// -- snip --

tuffynotes.cpp

// -- snip --

char choice;
Note n;
// For storing up to 100 notes.
Note notes[100];
int size = 0;
// used for looping until user is done
bool flag = true;
int main() {
  while (flag) {
    std::cout << "Welcome to TuffyNotes!\n";
    std::cout << "[C] Create a note\n[L] List notes\n[V] View note\n[E] Exit\nChoice: "; 
    std::cin >> choice;
    std::cout << "\n";
    switch (choice) {
      case 'C':
      case 'c':
        notes[size] = n.create_note();
        size++;
        break;
      // -- snip --
    }
  }
}

The output says

Please enter the note's title: 
Please enter the note: 

when it should first allow me to input the title before skipping straight to asking for input for the body.

Please enter the note's title:
Nolan D.
  • 25
  • 7
  • 2
    Groovy. Thanks. You've run up against [Why does std::getline() skip input after a formatted extraction?](https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction) You have to be very careful when mixing `>>` and `getline`. If you need `getline`, it's generally better to only use `getline` and then parse the line into the stuff you want. `std::stringstream` often helps here. – user4581301 Mar 25 '19 at 05:23
  • @user4581301 I'm assuming that you want me to replace the last two remaining cin statements in my code with getline statements. When I did this, I received an error. The cin statements were for an integer and for a character, and now they're giving m errors. – Nolan D. Mar 25 '19 at 05:38
  • Please make [mcve]s. One for the already shown code (it could use some work on the "minimal" and one for the modified code. This also servers the general principle to add information to the question instead of hiding it in comments. – Yunnosch Mar 25 '19 at 05:59
  • When you entered the value read into `choice`, the newline was left in the input buffer. The first call to `getline` reads that newline, and is happy because it reached a newline. You are less happy, though. – Jonathan Leffler Mar 25 '19 at 06:06
  • @JonathanLeffler So what do you suppose I do exactly? – Nolan D. Mar 25 '19 at 06:11
  • @Yunnosch I did my best to minify my code. – Nolan D. Mar 25 '19 at 06:11
  • Good, now work on the "C" and the "V", i.e. make it complete and verifiable. – Yunnosch Mar 25 '19 at 06:13
  • After you read `choice`, read up to and including the end of line so that `getline` doesn't read the end of that line for you. You might use `getline` again to read to the end of the line. Of course, this assumes your user isn't nasty and doesn't play tricks like hitting control-D (on Unix) after entering the choice character to send one character without newline to the input system. You might decide then that if the character after the choice is not a newline, you push it back into the input queue. In C terms, you'd use `getchar()` and `ungetc()`. In C++, you'd use equivalents. – Jonathan Leffler Mar 25 '19 at 06:13
  • @JonathanLeffler How would I put that into code? Sorry, I'm a CS student still learning. – Nolan D. Mar 25 '19 at 06:14
  • @JonathanLeffler I tried getchar(), did not work. Still get same error – Nolan D. Mar 25 '19 at 06:23
  • Which `getchar()` did you try? I gave a C function — I told you to use the C++ equivalent (but I'm not sure what that is and I'm too lazy to look it up because it isn't my problem – it's yours). If it didn't work, you didn't do it right — for some definition of 'right' that means "if it works, it might be OK; if it doesn't work, it is wrong". – Jonathan Leffler Mar 25 '19 at 06:25
  • I just imported stdio and stdlib and gave getchar a try. The program functions but I still get the exact same error. – Nolan D. Mar 25 '19 at 06:33
  • Just read [std::basic_istream::ignore](https://en.cppreference.com/w/cpp/io/basic_istream/ignore) and [std::basic_istream](https://en.cppreference.com/w/cpp/io/basic_istream) generally. – David C. Rankin Mar 25 '19 at 07:00
  • You can't only use `getline` because `getline` only gets `std::string`s. Once you have the line `string`, you have to convert the line into the datatype you need, an `int` in your case. [This answer is solving a slightly different problem](https://stackoverflow.com/a/55270632/4581301), the Asker misplaced an `ignore` in an attempt to get rid of a newline, but the solution is to do the exact same thing: eliminate the need to handle the newline. – user4581301 Mar 25 '19 at 14:38

0 Answers0