开发者

how to clear the unneccessary input stream in C++

开发者 https://www.devze.com 2022-12-20 05:37 出处:网络
I would like to make the user开发者_JAVA百科 input a center number of character, e.g. 10, however, the user might input more than 10.

I would like to make the user开发者_JAVA百科 input a center number of character, e.g. 10, however, the user might input more than 10.

for(int i = 0 ; i< 10 ; i++)
cin>>x;

The extra character could make my code crash since I will ask for input later.

How can I clear the input at this moment when the user input more than 10?

Thanks so much!


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

This should reset the failbit and ignore the bad input.


By the way, to avoid duplicating all that code every time, I once wrote a little template function to do that work:

template<typename InType> void AcquireInput(std::ostream & Os, std::istream & Is, const std::string & Prompt, const std::string & FailString, InType & Result)
{
    do
    {
        Os<<Prompt.c_str();
        if(Is.fail())
        {
            Is.clear();
            Is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        }
        Is>>Result;
        if(Is.fail())
            Os<<FailString.c_str();
    } while(Is.fail());
}

template<typename InType> InType AcquireInput(std::ostream & Os, std::istream & Is, const std::string & Prompt, const std::string & FailString)
{
    InType temp;
    AcquireInput(Os,Is,Prompt,FailString,temp);
    return temp;
}

The first overload may be preferred if you want to avoid copying, the second may be more convenient for builtin types. Usage examples:

//1st overload
int AnInteger;
AcquireInput(cout,cin,"Please insert an integer: ","Invalid value.\n",AnInteger);

//2nd overload (more convenient, in this case)
int AnInteger=AcquireInput(cout,cin, "Please insert an integer: ","Invalid value.\n");


cin goes into an error mode and stops doing anything if the user gives invalid input. You need to add a check for invalid input and a loop to retry.

for(int i = 0 ; i< 10 ; i++)
    while ( ( cin >> x ).rdstate() == ios::failbit ) {
        cin.clear();
        cin.ignore( numeric_traits<streamsize>::max(), '\n' );
    }

It's a lot of work, but you need to define some kind of policy for ignoring invalid input. There are other choices; this just ignores the remainder of the line.


This shows how to clear the entire buffer on an error.

from: http://support.microsoft.com/kb/132422

/* No special compile options needed. */ 

#include <iostream.h>

int ClearError(istream& isIn)        // Clears istream object
{
  streambuf*  sbpThis;
  char        szTempBuf[20];
  int         nCount, nRet = isIn.rdstate();

  if  (nRet)                        // Any errors?
  {
      isIn.clear();                 // Clear error flags
      sbpThis = isIn.rdbuf();       // Get streambuf pointer
      nCount = sbpThis->in_avail(); // Number of characters in buffer

      while (nCount)                // Extract them to szTempBuf
      {
          if  (nCount > 20)
          {
              sbpThis->sgetn(szTempBuf, 20);
              nCount -= 20;
          }
          else
          {
              sbpThis->sgetn(szTempBuf, nCount);
              nCount = 0;
          }
      }
  }

  return  nRet;
}

void main()
{
   int  n = 0, nState;
   while (n <= 100)
   {
      cout << "Please enter an integer greater than 100.\n";
      cin >> n;
      nState = ClearError(cin);   // Clears any errors in cin
   }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消