How To Clear an istream Object During Extraction (132422)



The information in this article applies to:

  • The C Run-Time (CRT), when used with:
    • Microsoft C/C++ for MS-DOS 7.0
    • Microsoft Visual C++ for Windows, 16-bit edition 1.0
    • Microsoft Visual C++ for Windows, 16-bit edition 1.5
    • Microsoft Visual C++ for Windows, 16-bit edition 1.51
    • Microsoft Visual C++ for Windows, 16-bit edition 1.52
    • Microsoft Visual C++, 32-bit Editions 1.0
    • Microsoft Visual C++, 32-bit Editions 2.0
    • Microsoft Visual C++, 32-bit Editions 2.1
    • Microsoft Visual C++, 32-bit Editions 4.0
    • Microsoft Visual C++, 32-bit Enterprise Edition 5.0
    • Microsoft Visual C++, 32-bit Professional Edition 5.0
    • Microsoft Visual C++, 32-bit Enterprise Edition 6.0
    • Microsoft Visual C++, 32-bit Professional Edition 6.0
    • Microsoft Visual C++, 32-bit Learning Edition 6.0

This article was previously published under Q132422

SUMMARY

Testing for errors during extraction is important. For example:
   int  n = 0;
   while (n <= 100) {cin >> n;}
				
This program is expecting a value greater than 100. If the user inputs a non-numeric value, the stream's fail bit is set, and the cin object becomes unusable. All subsequent extractions result in an immediate return with no value stored. Consequently, the program hangs (stops responding) in the while loop.

MORE INFORMATION

The clear() member function clears the fail bit. However, the istream object is still unusable. The sample code below clears the fail bit and extracts the unusable characters left in the streambuf object.

Sample Code

   /* 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
      }
   }
				

REFERENCES

iostream Class Library Reference, Chapter 1

Modification Type:MinorLast Reviewed:6/29/2004
Keywords:kbcode kbCRT kbhowto kbLangCPP KB132422