getline删除第一个字符;删除cin.ignore();不解决

时间:2017-01-31 07:56:45

标签: c++ cin getline truncation

int main()
{
for (int i = 0; i < 4; ++i)
    {
    cout << "Please enter Employee #" << (i+1) << "'s" << " name: ";
    cin.ignore();
    getline(cin, employee[i].employeeName);
    cout << "Please enter Employee #" << (i+1) << "'s hours worked: ";
    cin >> employee[i].hoursWorked;
    cout << "Please enter Employee #" << (i+1) << "'s hourly rate: ";
    cin >> employee[i].hourlyRate;
    cout << "Please enter Employee #" << (i+1) << "'s Federal Tax Rate: ";
    cin >> employee[i].fedtaxRate;
    cout << "Please enter Employee #" << (i+1) << "'s State Tax Rate: ";
    cin >> employee[i].statetaxRate;
    cout << endl;
    }

正如标题所说,我目前有cin.ignore();来帮助我们提供像Barkley,Charles&#34;这样的全名。 (它做得很好,除了它会截断第一个字符离开我们&#34; arkley,Charles&#34;打印时)但是当我删除cin.ignore();时,就像99%的已经回答的StackOverflow问题一样说,没有任何反应。事实上,它甚至变得更糟:在第二个循环中,它将采用第二个循环的第二行并将其放在第二个循环的第一行。这只是一团糟。哦,cin.getline也不起作用。我和cin.sync并没有骰子一起尝试过。常规普通老香草cin >>在第一线问题上导致相同的第二行。我不知道该怎么做。我还没有找到一篇SO文章来介绍这个(貌似)边缘案例。谢谢您的帮助。

1 个答案:

答案 0 :(得分:1)

与许多输入问题一样,问题仍然存在,因为您正在混合基于行和基于项目的输入。

最后的cin >> employee[i].statetaxRate;会使流指针指向紧跟在其类型的最后一个有效字符之后的位置。

这可能是该行末尾的换行符,所以,当您返回获取下一个名称(没有cin.ignore)时,它会将其读作空行。

您可能认为可以通过将cin.ignore置于循环的末尾来修复它,但是您可能会遇到其他问题。具体来说,由于该表单只是跳过一个字符,输入:

123<space><newline>

只会跳过<space>,您就会遇到完全相同的问题。

快速解决方法是简单地读取整个行的其余部分(在循环结束时):

{
    std::string junk;
    getline(cin, junk);
}

这将准备输入流,以便您在下一行的开头。

另一种可能性(这是首选,因为当你第一次进入abc时,它预期一个数字会让你感到悲伤)是读所有你的将项目作为行,然后使用字符串处理将它们放入数字变量,类似strtod()