Search code examples
c++parameter-passinguser-input

User Input as Argument C++


I am new to coding and was wondering why my code is not acting the way I intended. I build the code as a training program to help me practice what i have learned. The code seems to work fine, as expected, when I comment out lines 19 - 23,the multi line comment section, but when I don't that's when it starts to act unexpectedly.

#include <iostream>

int askUserNumber ()
{
    std::cout << "Please input a number: " << std::endl;  //ask user to input number
    int userNumber;                                       //define integer to store input
    std::cin >> userNumber;                               // get input from user

    return (userNumber);                                  // return input to caller
}

void printUserNumber (int userNumber)
{
    std::cout << "Your number input was: " << userNumber << std::endl; //print input to user screen
}

int main ()
{
    /*
    std::cout << "Please input your name: " << std::endl;      // ask user name
    int userName;                                         // variable to store user name
    std::cin >> userName;                                 // get user name
    */

    printUserNumber(askUserNumber());                       // call to askUserNumber to get user input to print to screen
    return(0);
}

Results(Without Commenting out code):

Please input your name:
Corey
Please input a number:
Your number input was: "someGarbageNumber"

It does't let me input a number at that part and it just prints out a random number.

Results(With Commenting out code):

Please input a number:
7
Your number input was: 7

This time it runs perfectly and there are no problems. I don't understand why the three lines asking for the users name cause it to not allow me to input a number when the function call for printUserNumber(askUserNumber()) gets to the point that it prints "Please input a number:" and doesn't allow me to input one. Thank you for any responses. I hope I wrote my question in a good format, and explained my problem in a clear and straight forward way. Hopefully the results will section will also allow for some clarity. Looking forward to a solution thanks again.


Solution

  • Because userName is an int and you are trying to use std::cin to read a sequence of non-numeric characters into it, the operation fails and leaves std::cin in a fail()ed state and so none of the following operator>> calls on std::cin will succeed in extracting further input characters.

    It does't let me input a number at that part and it just prints out a random number.

    Until C++11 the behavior was to leave the rhs unmodified, which in your case is an uninitialized int, hence the garbage you see when printing.

    You can see all of that in the reference of std::basic_istream::operator>>():

    • If extraction fails (e.g. if a letter was entered where a digit is expected), value is left unmodified and failbit is set. (until C++11)
    • If extraction fails, zero is written to value and failbit is set. If extraction results in the value too large or too small to fit in value, std::numeric_limits<T>::max() or std::numeric_limits<T>::min() is written and failbit flag is set. (since C++11)

    You can still recover from such fail() state in the stream by clearing its error state flags and ignoring what's in the buffer:

    int main()
    {
        std::cout << "Please input your name: " << std::endl; // ask user name
        int userName;                                         // variable to store user name
        std::cin >> userName;                                 // get user name
    
        if (!std::cin) // Check if `fail()`
        {
            std::cout << "input stream failure :-(" << '\n';
    
            // Clearing flags and input buffer
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        }
        else
        {
            std::cout << "Your name input was: " << userName << '\n';
        }
    
        printUserNumber(askUserNumber());                       // call to askUserNumber to get user input to print to screen
    
        return 0;
    }
    

    Output:

    Please input your name: 
    input stream failure :-(
    Please input a number: 
    Your number input was: 7
    

    The solution to get your desired behavior is simply to make userName a std::string for example. In which case the above code produces the output:

    Please input your name: 
    Your name input was: Corey
    Please input a number: 
    Your number input was: 7