none
std::getline and std::cin RRS feed

  • Question

  • When I write:

    int
    main (int argc, char *argv[])
    {
        std::string name;
        int length;

        //std::cin >> length;
        std::getline (std::cin, name);
         
    }

    the program pauses before the getline. However, when I write

    int
    main (int argc, char *argv[])
    {
        std::string name;
        int length;

        std::cin >> length;
        std::getline (std::cin, name);
         
    }

    the program pauses only before cin. I expected it to pause after the cin and before the getline. However, it does not do that and instead just assigns an empty string to name. The getline caused a pause in the first program...why shouldn't it cause a pause here?
    Monday, January 19, 2009 6:33 AM

Answers

  • No, name is empty in the second example.
     
    1. When the program executes, the input buffer is initially empty.
    2. "std::cin >> length;" executes. The program waits for input because there is no input to extract.
    3. The user types 123 and hits enter; the input buffer now contains "123\n".
    4. length is populated with the value 123; the input buffer now contains "\n".
    5. "std::getline(std::cin, name);" executes. std::getline reads all input through the next \n, populates name with everything preceeding the \n (nothing in this case) and discards the \n; the input buffer is now empty.
     
    What you need to do is get rid of that \n after 123 is extracted into length, before calling std::getline. Typically you would do this with std::ws or std::cin.ignore().
    • Edited by ildjarn Monday, January 19, 2009 7:39 PM typos
    • Marked as answer by Rong-Chun Zhang Friday, January 23, 2009 9:19 AM
    Monday, January 19, 2009 7:37 PM
  • Quote>Typically you would do this with std::ws or std::cin.ignore().

    Or std::cin.ws()

    (ws is implemented both as a manipulator and as a member
    function.)

    - Wayne



    Monday, January 19, 2009 9:44 PM

All replies

  • This behavior is because "std::cin >> length;" doesnt consume the whitespace (specifically the \n) after the integer is read in. Try "std::cin >> length >> std::ws;".
    Monday, January 19, 2009 7:22 AM
  • So, you are saying that name is always assigned the string "\n" in the second example? Is there a place where I can read about the general rules for when the program pauses and waits for input?
    Monday, January 19, 2009 7:29 PM
  • No, name is empty in the second example.
     
    1. When the program executes, the input buffer is initially empty.
    2. "std::cin >> length;" executes. The program waits for input because there is no input to extract.
    3. The user types 123 and hits enter; the input buffer now contains "123\n".
    4. length is populated with the value 123; the input buffer now contains "\n".
    5. "std::getline(std::cin, name);" executes. std::getline reads all input through the next \n, populates name with everything preceeding the \n (nothing in this case) and discards the \n; the input buffer is now empty.
     
    What you need to do is get rid of that \n after 123 is extracted into length, before calling std::getline. Typically you would do this with std::ws or std::cin.ignore().
    • Edited by ildjarn Monday, January 19, 2009 7:39 PM typos
    • Marked as answer by Rong-Chun Zhang Friday, January 23, 2009 9:19 AM
    Monday, January 19, 2009 7:37 PM
  • Quote>Typically you would do this with std::ws or std::cin.ignore().

    Or std::cin.ws()

    (ws is implemented both as a manipulator and as a member
    function.)

    - Wayne



    Monday, January 19, 2009 9:44 PM
  • Good point, Wayne. :-)
    Monday, January 19, 2009 9:47 PM