我正在查看this帖子和其他一些帖子。如果在输入缓冲区已经为空时调用ignore()会发生什么?我在下面的代码中观察到,如果在缓冲区已经为空时调用ignore(),它将无法工作并等待首先输入某个字符。
int main(void)
{
char myStr[50];
cin.ignore (std::numeric_limits<std::streamsize>::max(),'\n');
cout<<"Enter the String\n";
cin>>myStr;
// After reading remove unwanted characters from the buffer
// so that next read is not affected
cin.ignore (std::numeric_limits<std::streamsize>::max(),'\n');
}
cin.clear()之后,如果缓冲区已经为空,则ignore()会产生更多问题。我想在cin()安全之后清除缓冲区。但是,如果我不知道输入缓冲区的状态,即使它已经为空,我也会清楚怎么办?我是否必须首先检查输入缓冲区是否为空,使用cin.fail()或类似的东西?
其次,cin本身可能不安全,因为不允许空间。因此,某些SO帖子建议使用getline()给出here。但getline()是否也需要清除输入缓冲区或者总是安全吗?以下代码是否正常运行(现在可以使用,但现在确定它是否是安全代码)。
void getString(string& str)
{
do
{
cout<<"Enter the String: ";
getline(std::cin,str);
} while (str.empty());
}
其他SO参考: Ref 3
答案 0 :(得分:1)
分解main
:
int main(void)
{
char myStr[50];
cin.ignore (std::numeric_limits<std::streamsize>::max(),'\n');
一个坏主意,但你已经注意到了。流中必须有换行符,或者您坐等等。如果用户不期待这种行为,您可能会等待很长时间并且让用户感到沮丧。这是一个糟糕的场景。
cout<<"Enter the String\n";
cin>>myStr;
也是一个坏主意,但出于不同的原因。 >>
并不知道它应停止在49个字符以防止溢出myStr
。第50个角色发生了不好的事情。
// After reading remove unwanted characters from the buffer
// so that next read is not affected
cin.ignore (std::numeric_limits<std::streamsize>::max(),'\n');
这个是安全的。 >>
不会消耗换行符或任何其他空格,并且为了让流从控制台移交数据,必须有人输入并提供换行符。
}
一般的经验法则是ignore
,除非你有理由ignore
,如果你有理由,请立即忽略。不要等到下一个流操作到ignore
之前,如果这个操作是第一个的话会导致什么?或者之前的操作没有给ignore
留下任何东西?在您在流中留下您想要的ignore
d的操作之后ignore
。所以
std::string getfirstword()
{
std::string firstword;
if (std::cin >> firstword)
{
cin.ignore (std::numeric_limits<std::streamsize>::max(),'\n');
return firstword;
}
return ""; // or perhaps
// throw std::runtime_error("There is no first word.");
// is more appropriate. Your call.
}
很好,但是
std::string getfirstword()
{
cin.ignore (std::numeric_limits<std::streamsize>::max(),'\n');
std::string firstword;
if (std::cin >> firstword)
{
return firstword;
}
return "";
}
在所有圣洁的眼中,是一种冒犯。不要这样做。
对于getline
,它得到一条线。所有这一切直到文件末尾或行尾,以先到者为准。它也为你排队结束,所以你不必担心一个流浪的换行线后来会破坏你的醇厚。
如果您只想要部分线路,则必须将其分解。对此的典型用法是
std::string line;
if (std::getline(std::cin,line))
{
std::istringstream istr(line);
std::string firstword;
if (istr >> firstword)
{
// do something with firstword
}
else
{
// there is no firstword. Do something else.
}
}
getline
读取所有内容,包括换行符。它不再在流中,所以我认为这是安全的。你不必担心垃圾在线路末端徘徊。不过,您可能不得不担心下一行。