PRB: OFSTREAM Loses Character 0xff
PSS ID Number: Q111253
Article last modified on 09-01-1994

7.00 7.00a

MS-DOS


----------------------------------------------------------------------
The information in this article applies to:

 - Microsoft C/C++ for MS-DOS, version 7.0
 - Microsoft C/C++ for MS-DOS, version 7.0a
----------------------------------------------------------------------

SYMPTOMS
========

When using the Microsoft C/C++ compiler version 7.0, if a buffer that is
written out using the write member function of an ostream class has 0xff in
element 0, 511,1023, ..., then that character is lost in the write.

This problem is caused by a sign extension of the char to 0xffff when an
internal member function is called.

Common symptoms of this problem include having a file that was written out
with an fstream object smaller than the actual number of bytes written.

CAUSE
=====

The problem resides in streambuf::xsputn(). This function calls overflow(),
which takes an INT and passes in a char. Unfortunately, EOF has a special
meaning to overflow(), namely "ignore this character". 0xFF is sign-
extended to 0xFFFF, which is interpreted as EOF, and therefore, the 0xFF is
ignored if it is the character passed to overflow(). This is typically the
first character after the old buffer fills up, or in other words, the first
character of the new buffer.

RESOLUTION
==========

If only a space character is needed, then character 0x20 could be
substituted for character 0xff. If character 0xff is needed, then the
source code can be modified to correct the sign extension when overflow()
is called. The file that contains the function streambuf::xsputn() is
streamb.cxx, which is in the run-time library. In the function
streambuf::xsputn(), the line that reads

   if (overflow(*pBuf)==EOF)

should be changed to:

   if (overflow(*(unsigned char *)pBuf)==EOF)

This will not allow the sign extension to occur, and the size of the file
output from the sample below will be 512, not 511.

STATUS
======

Microsoft has confirmed this to be a problem in Microsoft C/C++ for MS-DOS,
version 7.0 and 7.0a. This problem was corrected in Microsoft Visual C++
for Windows, version 1.0.

MORE INFORMATION
================

The file streamb.cxx needs to be recompiled with the appropriate memory
model for the library that you are linking with. The source code can be
obtained from CompuServe in the libraries of the MSLANG forum (C7CRT1.ZIP
and C7CRT2.ZIP) or from Microsoft End User Sales by calling (800) 426-9400.

Sample Code
-----------

/*
  command line: cl /c file.c
  link /NOE streamb file, file;
*/
#include<fstream.h>
#include<memory.h>
char szBuf[512];
void main()
{
 ofstream Myfile("xxx.xxx",ios::binary | ios::out );
 memset( szBuf,(char)255,512);
 Myfile.write( szBuf, 512 );
}

Additional reference words: 7.00 7.00a
KBCategory: Prg
KBSubcategory:

=============================================================================

Copyright Microsoft Corporation 1994.
