跳过上次的cin输入

skipping over my last cin input

本文关键字:cin 输入      更新时间:2023-10-16

这是一个非常简单的程序,但我错过了一些东西。我被要求选择变量,这将是最有效的手段来存储数据,然后在用户输入这个信息后,我要使用cout来显示它。但由于某种原因,它跳过了最后一个cin语句,不允许我输入字符变量。我试过在最后一个问题的提示之前使用cin.ignore(),但没有运气。下面是代码:

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.00n";

    // 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 << "aaaaa";
    system("pause");
    return 0;
}

我的输出是这样的:

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 . . .

请说明情况并提前感谢您的帮助

代码的主要问题是您没有测试输入的结果:您总是需要在尝试读取后验证您的输入是否成功。如果你这样做了,你会注意到gnp_florida的输入失败了。一旦输入失败,std::istream对象将被置于故障模式,并且它们将不接受任何进一步的输入,直到故障模式为clear() ed。方便地将流转换为bool,即您可以使用类似

的内容。
if (!(std::cin >> value)) { report_error(); }

来测试流是否遇到错误(对于那些想挑剔答案的人:是的,我知道这个结构实际上没有经过到bool的转换,而是使用为流定义的operator!();然而,这个细节对于这个答案来说是相当不重要的)。

gnp_florida的问题实际上是双重的:

  1. 你的输入753896.45不是一个整数,而变量被声明为unsigned int。这本身并不是一个错误。然而,小数点不是整数格式的一部分,也就是说,输入将在小数点之前停止,小数点将成为下一个输入读取的字符。
  2. 753896被解释为一个整数,但是它太大了,不适合gnp_florida类型的unsigned short !unsigned short的范围很可能是065535(您可以通过打印std::numeric_limits<unsigned short>::min()std::numeric_limits<unsigned short>::max()来验证范围)。试图读取的值对于要存储的变量来说太大,会导致输入失败。

解决这个问题的方法是对gnp_florida使用double(显然,除了验证流处于良好状态之外):读取753896.45gnp_florida将成功并提取所有字符。使用double而不是float增加了打印值时恢复所有8位数字的机会。

您输入的753896.45是佛罗里达州的GNP,它是double类型,而程序期望的是unsigned short

当使用std::cin <<作为GNP时,它尝试将尽可能多的内容提取到变量中,而将其他内容留在缓冲区中。因此,由于735896.45不能全部放入short中,因此其中一些留在缓冲区中。

因此,下次您使用std::cin <<作为性别时,它不会麻烦地询问用户,它只是使用缓冲区中已经存在的数字,然后尝试将其转换为ASCII字符,最终成为'╠'

我建议的是,首先,不要为了在存储中节省一位而使用无符号整数(这可能是填充的)。无符号整数会产生大量的其他bug,这意味着你应该只在有充分理由的情况下使用它们(在这种情况下除外)。

其次,我想说的是,这是一个很好的做法,声明你的变量尽可能接近他们初始化的时候(在这种情况下,就在std::cin之前)。如果你这样做了,你可能就能自己看到bug了。