Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 清除输入缓冲区中的所有其他字符_C++_Buffer_Main - Fatal编程技术网

C++ 清除输入缓冲区中的所有其他字符

C++ 清除输入缓冲区中的所有其他字符,c++,buffer,main,C++,Buffer,Main,我试图控制一个小型控制台应用程序的使用,不希望用户键入任何超过一个字符的内容。到目前为止我所拥有的 int main() { char choice; string strChoice; /*Set the title bar title to Binary Calculator*/ system("title Binary Calculator 2014"); do{ Menu(); getline(cin,strChoice

我试图控制一个小型控制台应用程序的使用,不希望用户键入任何超过一个字符的内容。到目前为止我所拥有的

int main()
{
   char choice;
   string strChoice;

    /*Set the title bar title to Binary Calculator*/
      system("title Binary Calculator 2014");

    do{
      Menu();
      getline(cin,strChoice);
      choice = toupper(strChoice[0]); //convert value to uppercase for conformity
      DetermineChoice(choice);
   } while (mistakes < 3);
}
屏幕上到处都是虫子,我相信这是由do-while循环引起的,所以我需要刷新除第一个字符外的所有字符。同样,当我在程序第一次运行时选择B,然后我返回并再次尝试选择B时,它表示输入缓冲区中除了回车外没有任何内容

上面是我的int main。我将向您展示determine-choice函数和错误处理函数

void DetermineChoice(char value)
{
    /*
        Purpose: Determine what character was passed to value
        Pre: a hopefully valid character
        Post: Will go through cases below and then pass to another function
    */
  string binary;
  int decimal;

  switch (value)
  {
    case 'B': 
    case 'C': 
        ConversionOperation(value);
    case 'P': 
        cout << "Process File" << endl; 
        break;
    case '+':
    case '-':
    case '/':
    case '*':
    case '%': ArithmeticActions(value);
    case 'Q':
        PrintSummary();
        break;
    default: 
        HandleChoiceError(value); 
        break;
  }
}

最容易修补的:替换

cin.ignore(1);

表示忽略cin中的n个字符,但在找到c后停止,并且numeric_limits::max是streamsize类型中的最大值,是istream::ignore的一个特例,其中它表示无穷大


这将很好地适用于您的用例,因为用户输入通常是基于行的。这比丢弃输入缓冲区要好,因为输入缓冲区中的内容并不总是可预测的——有人可能会将文件传输到您的程序,终端可能会奇怪地进行缓冲,用户可能是非常快的打字员,等等。批量丢弃输入缓冲区有时会产生奇怪的结果,但是如果在一个命令后丢弃该行的其余部分,没有人会感到非常惊讶。

最容易修补的方法是:替换

cin.ignore(1);

表示忽略cin中的n个字符,但在找到c后停止,并且numeric_limits::max是streamsize类型中的最大值,是istream::ignore的一个特例,其中它表示无穷大


这将很好地适用于您的用例,因为用户输入通常是基于行的。这比丢弃输入缓冲区要好,因为输入缓冲区中的内容并不总是可预测的——有人可能会将文件传输到您的程序,终端可能会奇怪地进行缓冲,用户可能是非常快的打字员,等等。批量丢弃输入缓冲区有时会产生奇怪的结果,但是如果在命令之后丢弃行的其余部分,没有人会感到非常惊讶。

没有刷新std::istream这样的事情。刷新是一个输出概念。由于控制台有多个输入缓冲区,即std::istream的std::streambuf和操作系统控制台缓冲区中的输入缓冲区,因此没有可靠的方法来实际删除所有输入字符。您可以通过禁用unix上的concole缓冲区来删除所有字符。您可以使用tcsetattr和tcgetattr清除ICANON标志

对于您的需要,最好的方法是忽略当前行上的所有字符,或者删除输入缓冲区中的所有字符:

要删除当前行上的所有字符,请使用std::istream::ignore,其中包含要忽略的最大字符数和要停止的字符,即换行符的“\n”。为了根据需要匹配尽可能多的字符,您需要传递神奇的值std::numeric_limits::max一个相当大的值,比如10000,也可以满足实际需要。 您可以使用in.rdbuf->in\u avail找到立即可用的字符下限。此函数确定在没有流阻塞的情况下可以读取多少字符。实际上,这是std::istream的输入缓冲区中的字符数,例如In.ignorein.rdbuf->In_avail应该删除所有字符。 从长远来看,我会使用in.ignorecount,“\n”和一个合适的计数,我显然会使用std::numeric_limits::max,但您似乎不能使用这个函数,可能是因为我目前正在帮助您完成家庭作业。当然,std:getline已经读取了整行内容,也就是说,实际上没有任何内容可以忽略

请注意,您应该始终验证输入操作是否实际成功:

if (std::getline(std::cin, line)) {
    // process successful line
}
else {
    // deal with the input having failed
}
请注意,即使行是空的,输入一行也是成功的!在访问第一个字符之前,您应该验证它是否存在,例如,使用!行。空的

顺便说一句,正如你已经明确提到的:这实际上并没有忽略任何字符。相反,它会清除流错误标志,即正在测试的内容,以验证输入是否成功。注意:任何函数的参数都必须是值范围为unsigned char加EOF的非负int。由于char往往是有符号的,因此传递任意char(例如strChoice[0])可能会导致未定义的beheavior(例如,当传递我的第二个名字的ISO-Latin-1或UTF-8表示形式时)。通常的解决方法是使用

std::toupper(static_cast<unsigned char>(strChoice[0]))

没有冲洗std::istream这样的事情。刷新是一个输出概念。由于控制台有多个输入缓冲区,即std::istream的std::streambuf和操作系统控制台缓冲区中的输入缓冲区,因此没有可靠的方法来实际删除所有输入字符。您可以通过禁用concole的缓冲区o来删除所有字符 n unix您可以使用tcsetattr和tcgetattr清除ICANON标志

对于您的需要,最好的方法是忽略当前行上的所有字符,或者删除输入缓冲区中的所有字符:

要删除当前行上的所有字符,请使用std::istream::ignore,其中包含要忽略的最大字符数和要停止的字符,即换行符的“\n”。为了根据需要匹配尽可能多的字符,您需要传递神奇的值std::numeric_limits::max一个相当大的值,比如10000,也可以满足实际需要。 您可以使用in.rdbuf->in\u avail找到立即可用的字符下限。此函数确定在没有流阻塞的情况下可以读取多少字符。实际上,这是std::istream的输入缓冲区中的字符数,例如In.ignorein.rdbuf->In_avail应该删除所有字符。 从长远来看,我会使用in.ignorecount,“\n”和一个合适的计数,我显然会使用std::numeric_limits::max,但您似乎不能使用这个函数,可能是因为我目前正在帮助您完成家庭作业。当然,std:getline已经读取了整行内容,也就是说,实际上没有任何内容可以忽略

请注意,您应该始终验证输入操作是否实际成功:

if (std::getline(std::cin, line)) {
    // process successful line
}
else {
    // deal with the input having failed
}
请注意,即使行是空的,输入一行也是成功的!在访问第一个字符之前,您应该验证它是否存在,例如,使用!行。空的

顺便说一句,正如你已经明确提到的:这实际上并没有忽略任何字符。相反,它会清除流错误标志,即正在测试的内容,以验证输入是否成功。注意:任何函数的参数都必须是值范围为unsigned char加EOF的非负int。由于char往往是有符号的,因此传递任意char(例如strChoice[0])可能会导致未定义的beheavior(例如,当传递我的第二个名字的ISO-Latin-1或UTF-8表示形式时)。通常的解决方法是使用

std::toupper(static_cast<unsigned char>(strChoice[0]))

std::getline,然后检测多个字符并抛出一个错误,或者只处理第一个字符并忽略其余字符。getline不是也有问题吗?您指的是什么问题?它吸收到“\n”之前的所有内容,丢弃“\n”并向您显示行。如果行长度超过一个字符,您就知道输入是假的。如果它有一个字符,并且它与您的条件不匹配,那么同样是伪输入。如果它有一个字符并且满足了您的一个匹配项,那么您就可以开始了。也许你在想一些我不认为不太可能的事情。好吧,是的,我记得问题是getline然后使用cin>>choice或cin。get我需要在系统暂停后刷新缓冲区,我相信这就是冲突的地方,但我正在更新我的问题,我不知道你在说什么。我说的是std::字符串行;std::getlinecin,line;`并使用line,精确地制作我上面描述的内容。cin>>choice和cin.get在我描述的内容中都没有。您的代码更新似乎反映了这一点,那么问题是什么?一旦你这样做了,输入缓冲区就不需要刷新。std::getline,然后检测多个字符并抛出一个错误,或者只处理第一个字符而忽略其余字符。getline不是也有问题吗?你指的是什么问题?它吸收到“\n”之前的所有内容,丢弃“\n”并向您显示行。如果行长度超过一个字符,您就知道输入是假的。如果它有一个字符,并且它与您的条件不匹配,那么同样是伪输入。如果它有一个字符并且满足了您的一个匹配项,那么您就可以开始了。也许你在想一些我不认为不太可能的事情。好吧,是的,我记得问题是getline然后使用cin>>choice或cin。get我需要在系统暂停后刷新缓冲区,我相信这就是冲突的地方,但我正在更新我的问题,我不知道你在说什么。我说的是std::字符串行;std::getlinecin,line;`并使用line,精确地制作我上面描述的内容。cin>>choice和cin.get在我描述的内容中都没有。您的代码更新似乎反映了这一点,那么问题是什么?一旦您这样做,输入缓冲区就不需要刷新。我应该声明,除了string、iomanip、iostream、fstream和ctype之外,不能添加任何其他库。然后写入streamsizesize_t-1/2,而不是numeric_limits::max。它看起来不太漂亮,但意思是一样的。size_t-1是size_t中的最大值,因为size_t是无符号的,而streamsize是size_t的有符号对应项,所以它的最大值将是size_t的一半。仍然不能使用它们,它们可能是STL的一部分,但我的教授不接受我们没有学习过的函数。相信我,我因为使用三元法而被扣分。我只想拿到我不需要上大学的学位
敖。尽管他们的局限性让我跳出框框思考,这是肯定的。对不起,那就用10万吧。它将涵盖你所有的用例。哈哈!是的,我会尝试一下,但是80不起作用,因为这是控制台应用程序的大小?我应该声明,除了string、iomanip、iostream、fstream和ctype之外,不能添加任何其他库。然后写streamsizesize_t-1/2而不是numeric_limits::max。它看起来不太漂亮,但意思是一样的。size_t-1是size_t中的最大值,因为size_t是无符号的,而streamsize是size_t的有符号对应项,所以它的最大值将是size_t的一半。仍然不能使用它们,它们可能是STL的一部分,但我的教授不接受我们没有学习过的函数。相信我,我因为使用三元法而被扣分。我只想拿到我不需要上大学就可以编写lmao的学位。尽管他们的局限性让我跳出框框思考,这是肯定的。对不起,那就用10万吧。它将涵盖你所有的用例。哈哈!是的,我会试试这个,但是80不工作,因为这是控制台应用程序的大小吗?谢谢你的这篇文章,它为我打开了很多。是的,这是一个家庭作业,但我从不要求任何人为我写任何东西:我讨厌看到它。当有人提到使用这个或其他什么的时候,我通常可以理解代码的其余部分。我只是不知道到底该在谷歌输入什么。谢谢迪特玛+1@EasyBB:该死!我曾希望不经表决就得到接受的答案,然后再得到一顶帽子当然,由于我进一步改进了答案,指出了其他问题,我想,接受你的答案的可能性很小,因为WhozCraig没有给出答案,但你们两人都帮了我大忙。伙计,我忘了带帽子了@EasyBB Deitmar写下了可靠的答案,我没有问题勾选这个,只是因为Dietmar已经因为别人的上涨而失去了他的帽子=P@EasyBB:别担心,这只是一件愚蠢的事;我已经收集了比看起来合理的更多的帽子。谢谢你的这篇文章,它为我打开了很多。是的,这是一个家庭作业,但我从不要求任何人为我写任何东西:我讨厌看到它。当有人提到使用这个或其他什么的时候,我通常可以理解代码的其余部分。我只是不知道到底该在谷歌输入什么。谢谢迪特玛+1@EasyBB:该死!我曾希望不经表决就得到接受的答案,然后再得到一顶帽子当然,由于我进一步改进了答案,指出了其他问题,我想,接受你的答案的可能性很小,因为WhozCraig没有给出答案,但你们两人都帮了我大忙。伙计,我忘了带帽子了@EasyBB Deitmar写下了可靠的答案,我没有问题勾选这个,只是因为Dietmar已经因为别人的上涨而失去了他的帽子=P@EasyBB:别担心,这只是一件愚蠢的事;我已经收集了比看起来合理的更多的帽子。
cin.ignore(n, c);
if (std::getline(std::cin, line)) {
    // process successful line
}
else {
    // deal with the input having failed
}
std::toupper(static_cast<unsigned char>(strChoice[0]))