0

this is a pretty simple program but I'm missing something. I was asked to choose variables that would be the most efficient means to store data and then after the user enters this info I am to use cout to display it. But for some reason it skips past the last cin statement and doesn't allow me to enter a char variable. I have tried using cin.ignore() before the prompt on the last question but with no luck. Here is the code:

using namespace std;

int main()
{
    unsigned int population;
    float avg_income, hourly_wage;
    unsigned short int students, gnp_florida;
    char gender;

    // Instructions for all answers

    cout << "For all answers don't type a comma(,). For example the number 4,598,453.00 should be listed";
    cout << " as 4598453.00\n";


    // Get user input and assign it to the variables

    cout << "What is the population of the US?: ";
    cin >> population;
    cout << "What is the average family income in the US?: ";
    cin >> avg_income;
    cout << "Give the hourly wage of 1 family member: ";
    cin >> hourly_wage;
    cout << "Enter the total number of students attending SPC: ";
    cin >> students;
    cout << "What is the total GNP of Florida?: ";
    cin >> gnp_florida;
    cout << "Enter a gender (M for male or F for female): ";
    cin >> gender;

    // Display the variable's values using cout

    cout << "These are your answers......\n ";
    cout << "The total US population is " << population << endl;
    cout << "The average family income in the US is " << avg_income << endl;
    cout << "The hourly wage of 1 person in a household is " << hourly_wage << endl;
    cout << "The number of students attending SPC is " << students << endl;
    cout << "The GNP for Florida is " << gnp_florida << endl;
    cout << "The gender you entered is " << gender << endl;


    // Make the program beep 5 times using escape sequences
    cout << "\a\a\a\a\a";

    system("pause");
    return 0;
}

This is what my output looks like:

For all answers don't type a comma(,). For example the number 4,598,453.00 should be listed as 4598453.00
What is the population of the US?: 300000000
What is the average family income in the US?: 53453.24
Give the hourly wage of 1 family member: 15.35
Enter the total number of students attending SPC: 30253
What is the total GNP of Florida?: 753896.45
Enter a gender (M for male or F for female): These are your answers......
        The total US population is 300000000
The average family income in the US is 53453.2
The hourly wage of 1 person in a household is 15.35
The number of students attending SPC is 30253
The GNP for Florida is 52428
The gender you entered is ╠
Press any key to continue . . .

Please explain what's going on and thank you in advance for your help

  • The right tool to solve such problems is to use your debugger, but not to ask at Stack Overflow before you did so. Tell us all your observations you made when inspecting your code stepping through line by line in 1st place. Also you might want to read [**How to debug small programs (by Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)**] At least leave us with a **[MCVE]** that reproduces your problem. (This is a personal stock comment provided by πάντα ῥεῖ™) – πάντα ῥεῖ Aug 20 '16 at 20:15
  • What is type of `gnp_florida`? Which numbers can it hold? – Revolver_Ocelot Aug 20 '16 at 20:26
  • Why is gnp_florida a short when you are entering a floating point number? – NathanOliver Aug 20 '16 at 20:40
  • @πάνταῥεῖ Please see http://meta.stackoverflow.com/questions/332858/is-this-an-appropriate-stock-comment – Barmar Aug 20 '16 at 20:54
  • Thank you for your help. I need to get a little better at using my debugger. Do you know why I got the behavior that I did? Why is it that after entering the wrong data type I didn't get an error, it just skipped over the next input stream and on to the rest of the program –  Aug 20 '16 at 20:59

2 Answers2

2

The primary problem with your code is that you do not test the result of your inputs: you always need to verify that your input was successful after trying to read. If you had done so you would have noticed that that the input of gnp_florida failed. Once an input failed std::istream objects are put into failure mode and they won't accept any further input until the failure mode is clear()ed. Conveniently streams convert to bool, i.e., you can use something like

if (!(std::cin >> value)) { report_error(); }

to test whether the stream encountered an error (for those about to nitpick the answer: yes, I'm aware that this construct actually doesn't go through the conversion to bool but uses the operator!() defined for stream; this detail is rather immaterial for this answer, though).

The problem with gnp_florida is actually two-fold:

  1. Your input 753896.45 is not an integer while the variable is declared as unsigned int. That, per se, isn't an error. However, a decimal point isn't part of the integer format, i.e., the input would stop right before the decimal point which would become the character read by the next input.
  2. The value 753896 is interpreted as an integer but it is too big to fit into an unsigned short which is the type of gnp_florida! The range for unsigned short is most likely 0 to 65535 (you can verify the range by print std::numeric_limits<unsigned short>::min() and std::numeric_limits<unsigned short>::max()). Attempting to read a value which is too big for the variable it is to be stored in causes the input to fail.

The fix to the problem is to use a double for gnp_florida (obviously, in addition to verifying that the stream is in a good state): reading of 753896.45 for gnp_florida will be successful and extract all of the character. Using a double instead of a float increases the chances to recover all 8 digits when printing the value.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
0

You typed in 753896.45 for the GNP of Florida, which is a double type, when the program expected an unsigned short.

When using std::cin << for the GNP, it tries to extract as much as it can into the variable, with anything else being left inside the buffer. So since the 735896.45 can't all fit into a short, some of it is left in the buffer.

So therefore, the next time you use std::cin << for the gender, it doesn't bother asking the user, it simply uses the digits already in the buffer and then tries to convert it to an ASCII character, which ends up being '╠'.

What I would recommend is firstly, not to use Unsigned integers just for the sake of saving one bit in storage (which is probably padded anyway). Unsigned integers create loads of other bugs, which mean that you should only use them if you have a really good reason to (not in this case).

Secondly, I would say that it is good practice to declare your variables as close as possible to when they are initialized (in this case right before the std::cin). If you had done that, you would proabably be able to see the bug yourself.