discovering a bug with the cin and cout streams

A reader had sent in the following request for help, from my section in the material which deals with cin, cout and basic serialization using C++:

using bloodshed and your code, Listing 4.1 (pg 46 – 48)in Learning C++ by
Making Games compiles well but skips the input stage for amorphouseObject.
It asks the question (cout) but does not wait for the answer before it asks
the next question. It also did it for my students with their code. Any
ideas why?

Thanks!

I sat down and went through the sample code to see what was happening. Sure enough, midway through the example, it appeared as if an extra return character was somehow getting into the cin input stream and mucking up some of the input. For a quick recap, let’s look at what was originally posted:


/*************************************
 Learn C++ Programming by Making Games
 Project 4.1 - Game of Funny Headlines
*************************************/

#include 
#include 
using namespace std;

int main()
{
  // First, let's welcome the user
  cout << "Welcome to the C++ News Network!" << endl << endl;

  // Then, let's input several values to plug into our headlines...
  // Note that the questions don't always match the names of the
  // variables because we are trying to surprise the player.

  string userName;
  cout << "Please type in your first name: " << endl;
  cin >> userName;

  int smallNumber;
  cout << "How many siblings do you have?" << endl;
  cin >> smallNumber;

  float largeNumber;
  cout << "How much money would you like to earn every year?" << endl;
  cin >> largeNumber;

  string color;
  cout << "Tell us your least favourite color:" << endl;
  cin >> color;

  string amorphousObject;
  cout << "Which vegetables have the weirdest shapes?" << endl;
  getline( cin, amorphousObject );

  string deadGuy;
  cout << "Name a famous dead person:" << endl;
  getline( cin, deadGuy );

  string celebrityActor;
  cout << "Who is your favorite actor?" << endl;
  getline( cin, celebrityActor );

  string politician;
  cout << "Name a current world leader:" << endl;
  getline( cin, politician );

  string cartoonCharacter;
  cout << "Who is your favourite cartoon character?" << endl;
  getline( cin, cartoonCharacter );

  string weirdGroup;
  cout << "Name a hobby or a profession you find scary: " << endl;
  getline( cin, weirdGroup );

  string somethingGross;
  cout << "Name a food item you detested as a child: " << endl;
  getline( cin, somethingGross );

  // Finally, let's print out the headlines!
  cout << endl << endl << endl
       << "And now, today's headlines from the C++ News Wire:" << endl;
  cout << "--------------------------------------------------" << endl;

  cout << "ALIENS SHAPED LIKE " << color << " " << amorphousObject
       << " INVADE THE EARTH, KIDNAP " << celebrityActor << ", "
       << "RESURRECT " << deadGuy << "!" << endl << endl;

  cout << userName
       << " RELEASES NEW ALBUM! " << smallNumber
       << " COPIES EXPECTED TO BE SOLD!"
       << endl << endl;

  cout << politician << " CAUGHT IN LOVE TRIANGLE WITH "
       << cartoonCharacter << " AND SECRET "
       << weirdGroup << " CULT LEADER!" << endl << endl;

  cout << "WORLD'S LARGEST BABY BORN - WEIGHS " << largeNumber
       << " POUNDS, EATS " << smallNumber << " TONS OF "
       << somethingGross << " EVERY DAY!" << endl << endl;

  // And we're done!
  return 0;
}

Innocent enough to be sure...

Upon executing this little piece of code, the request for input on line 33 would "skip" without receiving anything from the console, moving ahead to the request for input on line 37. I tried playing with the different uses of "cin" along with "getline" to reproduce / remove this "input skipping". I commented out blocks of the code to try to isolate any extra return characters from somehow ending up in the input stream buffer (denoted by cin) until at last I discovered a workaround.

the workaround

If you'll notice in the source code, I'm switching between several different data types for grabbing input from the console. The code is requesting string / char data, ints, floats and more strings. Even going through C++ manuals and references couldn't account for the "input skip".

It was only when I tried grouping the input data types together, that the code started working as intended.


/*
 * Project4_1.cpp
 *
 *  Created on: Jan 7, 2010
 *      Author: Administrator
 */

#include 
#include 

using namespace std;

int main()
{
  // First, let's welcome the user
  cout << "Welcome to the C++ News Network!" << endl << endl;

  // Then, let's input several values to plug into our headlines...
  // Note that the questions don't always match the names of the
  // variables because we are trying to surprise the player.

  char userName[80];
  char color[80];
  char amorphousObject[80];
  int smallNumber = 0;
  double largeNumber = 0.0;

  cout << "Please type in your first name: ";
  cin.getline(userName,80);

  cout << "Tell us your least favourite color: ";
  cin.getline(color, 80 );

  cout << "Which vegetables have the weirdest shapes?: ";
  cin.getline( amorphousObject, 80 );

  string deadGuy;
  cout << "Name a famous dead person:" << endl;
  getline( cin, deadGuy );

  string celebrityActor;
  cout << "Who is your favorite actor?" << endl;
  getline( cin, celebrityActor );

  string politician;
  cout << "Name a current world leader:" << endl;
  getline( cin, politician );

  string cartoonCharacter;
  cout << "Who is your favourite cartoon character?" << endl;
  getline( cin, cartoonCharacter );

  string weirdGroup;
  cout << "Name a hobby or a profession you find scary: " << endl;
  getline( cin, weirdGroup );

  string somethingGross;
  cout << "Name a food item you detested as a child: " << endl;
  getline( cin, somethingGross );

  cout << "How many siblings do you have?: ";
  cin >> smallNumber;

  cout << "How much money would you like to earn every year?: ";
  cin >> largeNumber;

  // Finally, let's print out the headlines!
  cout << endl << endl << endl
       << "And now, today's headlines from the C++ News Wire:" << endl;
  cout << "--------------------------------------------------" << endl;

  cout << "ALIENS SHAPED LIKE " << color << " " << amorphousObject
       << " INVADE THE EARTH, KIDNAP " << celebrityActor << ", "
       << "RESURRECT " << deadGuy << "!" << endl << endl;

  cout << userName
       << " RELEASES NEW ALBUM! " << smallNumber
       << " COPIES EXPECTED TO BE SOLD!"
       << endl << endl;

  cout << politician << " CAUGHT IN LOVE TRIANGLE WITH "
       << cartoonCharacter << " AND SECRET "
       << weirdGroup << " CULT LEADER!" << endl << endl;

  cout << "WORLD'S LARGEST BABY BORN - EATS " << smallNumber << " TONS OF "
       << somethingGross << " EVERY DAY!" << endl << endl;

  // And we're done!

  return 0;
}

hope that helps!