C++/Getline

Advertisement


Question
I'm just learning C++ so this is probably one of the most basic questions You will ever get: Here is my code:
#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;

int main()
{
    int age;
    string zipcode,name,address;
    cout << "Please enter your name\n";
    cin >> name;
    cout << "Please enter your age\n";
    cin >> age;
    cout << "Please enter your zipcode\n";
    cin >> zipcode;
    cout << "Please enter your address\n";
    getline(cin,address);
    cout << address;
    
    
    cout << "Your name is " << name << ", you are "<< age << " years old, your zipcode is " << zipcode << ", and you live at " << address << "\n";

system("PAUSE");
}

What happens when I try to run this is it gets through perfectly fine until I get to the line getline(cin,address);
when it seemingly skips this line and displays "Your name is..." and the rest of that minus the address. Do you know why it doesn't stop to get the user's address? Thanks in advance

Answer
The reason is that the previous read from cin into the zipcode string extracted all characters from cin, skipping leading white space, until the next white space character was encountered - in this case the end of the line. This white space character is the next available input character from cin.

So the next available character from cin is the end of line terminating your input of the zip code. getline is called, extracts the next available character from cin, finds it is the end of line from the previous read, and returns, throwing away the end of line character it extracted from cin.

So what you need is a dummy read from cin before you call getline to extract the spare end of line character from the zipcode input. The most obvious way is to call getline again:

    cin >> zipcode;
    cout << "Please enter your address\n";
    getline(cin,address); // extract newline from previous read
    getline(cin,address); // read the address


Alternatively you could call get on cin:

    cin >> zipcode;
    cout << "Please enter your address\n";

    char dummy(0);         // extract newline from previous read
    std::cin.get(dummy);
    assert( '\n'==dummy );

    getline(cin,address); // read the address

Note I added an assertion check to ensure the character read was the expected end of line character. Include cassert to use the assert macro, and note that the macro typically only has an effect in debug builds (the macro NDEBUG needs to be undefined at the point the assert macro is defined). When assert is not active (i.e. NDEBUG is defined) it does nothing. The test passed to it is ignored. This is important because it means you should do no 'real' work in an assertion. Doing so is insidious as your code will do what you wish until you perform a release (production) build whereupon all the work done in asserts disappears!

On the other hand when assert is active (NDEBUG is not defined) the test you pass to it is evaluated and if false (i.e. compares equal to 0) writes information about the failure such as source file name and line number to standard error stream and calls abort. The current Visual C++ version of assert pops up a dialog box with this information when debugging and asks whether to abort, debug the application or ignore the problem.

Judicious use of assert can help locate problems while having no effect on the production release of the code. They are best used, as the name implies, when you know something must be true if the program is operating correctly, as is the case above. The whole point of reading the dummy character from cin was to extract the '\n' character left over from the previous read, so we can assert that after the read dummy must have the value of '\n' if the program is functioning as expected. Asserts are useful for preconditions (things that must be true before doing some operation), postconditions (as here, things that must be true after performing some operation), and invariants (things that should not have change before and after doing some operation).

Hope this helps  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.