C++ cin.clear()的意外行为;

C++ cin.clear()的意外行为;,c++,cin,C++,Cin,我想做的是: 我想要一个将姓名存储到char* 我打算使用cin.getline和cin.clear进行输入 错误安全 规则是:必须最多存储10个名称,或者在输入后中断 在这两种情况下,之后的名称必须在cout上加上每行1个名称 我的循环应该做什么:在下一个循环开始之前,将最大名称字母和所有扩展最大长度的字母从标准输入中删除 do { cin.getline(szInputRef, MAX_NAME_LEN); sizeLastLen = cin.gcount(); sz

我想做的是:

我想要一个将姓名存储到
char*

我打算使用cin.getline和cin.clear进行输入 错误安全

规则是:必须最多存储10个名称,或者在输入
后中断

在这两种情况下,之后的名称必须在cout上加上每行1个名称

我的循环应该做什么:在下一个循环开始之前,将最大名称字母和所有扩展最大长度的字母从标准输入中删除

do
{
    cin.getline(szInputRef, MAX_NAME_LEN);
    sizeLastLen = cin.gcount();
    szpNames[sizeIndex] = new char[sizeLastLen];
    strncpy (szpNames[sizeIndex], szInputRef, sizeLastLen);
    szpNames[sizeIndex][sizeLastLen] = '\0';
    sizeIndex++;
    cin.clear();
}
while ((sizeIndex < 10) &&(szpNames[sizeIndex - 1][0] != '.'));

for (sizeIndex = 0; sizeIndex < 10; sizeIndex++)
{
    if (szpNames[sizeIndex][0] == '.')
    {
        break;
    }

    cout << szpNames[sizeIndex] << endl;
}
输出为:

ig
se
nol
s
如果输入为>(最大名称*2) 应用程序崩溃,因为第二次输入时,检查似乎没有出现。 所以在阅读了所有关于cin.clear()的文档之后

我无法理解为什么在调用cin.clear()后,输入仍然存在以保存。 甚至没有任何扩展输入行为的Clou在没有cin.getline检查的情况下被存储,因此应用程序可能会崩溃


谁能解释一下我理解的错误或代码中的逻辑错误是什么吗?

丢弃输入流中的所有内容通常不是一件有用的事情。例如,有人可能会向stdin提供一个文件,在这种情况下,您会放弃所有内容,或者您的操作系统可能会以不同于您预期的方式进行缓冲,最终导致不可预测的结果。您真正想要做的是忽略当前输入行的其余部分。最简单的方法就是说

#include <iostream>
#include <limits>

std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

顺便说一下,您还应该防止不可恢复的I/O错误和“错误”,例如文件结尾。目前,如果有人在你的程序运行时按Ctrl+D(Unix)或Ctrl+Z(Windows),它会做一些有趣的事情。当然,如果您使用
std::string
std::getline

cin.clear()
只是清除任何错误标志,您可能需要一些
cin.ignore(…)
的变体。为什么不使用
std::string
?因为了解char*是什么是一个家庭作业,然后再了解std::string的区别。我觉得很无聊,所以我想通过确保输入错误的安全性来扩展任务。但是我们不完全确定如何调用cin.ignore来丢弃stdin中排队的所有内容。在那之后,我对cin.clear()进行了反复思考,认为这样做就行了。但可能我错了。使用cin.ignore会使循环无限。@RetiredInja我用std::ignore调试了它,在修复了无限循环错误后,它的行为与
cin.clear()完全相同。这正是我要找的。我只是无法抽象出信息,get行消耗了换行符。非挥发性物质。关于行为的一个小问题仍然留给我:如果输入至少比最大输入大1倍,那么为什么应用程序会崩溃?据我所知,我并没有丢弃剩余的一行,所以为什么第二次从stdin中读取的内容要多于maxmanamelen,而不是通过getline再次限制读取量呢?这是一个无关的bug。新分配的缓冲区太短一个字节(即,将空终止符写入缓冲区末尾一个字节)。
#include <iostream>
#include <limits>

std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if(std::cin.fail()) {
  std::cin.clear();
  std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}