gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 06:33:48 32 4
gpt4 key购买 nike

我想做的事情:

我想要一个将名称存储到 char* 数组中的代码

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

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

在这两种情况下,名称都必须放在 cout 上,每行 1 个名称。

我的循环应该做什么:接受最多 MAX_NAME_LEN 个字母,并且在下一个循环开始之前,应该将超出最大长度的所有内容从标准输入中丢弃。

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;
}

但实际上发生了什么:扩展了 MAX_NAME_LEN 个字母数的输入在没有检查的情况下被用作下一个输入。所以假设我们说测试用例 MAX_NAME_LEN 是 3

并输入:

ig
se
nols

输出将是:

ig
se
nol
s

如果输入是 > (MAX_NAME_LEN * 2)该应用程序崩溃至于第二个输入检查似乎没有出现。所以在阅读完 cin.clear() 的文档之后

我不明白为什么输入在调用 cin.clear() 之后还存在并被保存。如果没有 cin.getline 检查,甚至不会存储任何扩展输入行为的 Clou,因此应用程序可能会崩溃。

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

最佳答案

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

#include <iostream>
#include <limits>

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

在哪里std::numeric_limits<std::streamsize>::max()std::streamsize中最大的数字std::istream::ignore 的类型和特例它意味着无限。这意味着:忽略无限多个字符或到下一个 '\n' , 以先到者为准。

但是,您不能无条件地执行此操作,因为 std::istream::getline如果缓冲区足够大,则使用换行符;你会忽略每一行。仅当该行太长而无法放入缓冲区时才必须执行它。发生这种情况时,std::istream::getlinefailbit , 所以我们最终得到

if(std::cin.fail()) {
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 .

关于c++ - cin.clear() 的意外行为;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27099638/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com