goodbit stream state

J

john

In TC++PL3, in 21.3.3, the following definition of ios_base is provided:

class ios_base{
public:
// ...

typedef implementation_defined2 iostate;
static const iostate badbit, // stream is corrupted
eofbit, // end-of-file seen
failbit, // next operation will fail
==> goodbit; // goodbit==0

// ...
};


What does "goodbit==0" exactly mean?
 
M

Miguel Guedes

john said:
In TC++PL3, in 21.3.3, the following definition of ios_base is provided:

class ios_base{
public:
// ...

typedef implementation_defined2 iostate;
static const iostate badbit, // stream is corrupted
eofbit, // end-of-file seen
failbit, // next operation will fail
==> goodbit; // goodbit==0

// ...
};


What does "goodbit==0" exactly mean?

Means literally that everything is ok. 'goodbit' has no bits set and therefore
means that the IO state is not in error.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

In TC++PL3, in 21.3.3, the following definition of ios_base is provided:

class ios_base{
public:
// ...

typedef implementation_defined2 iostate;
static const iostate badbit, // stream is corrupted
eofbit, // end-of-file seen
failbit, // next operation will fail
==> goodbit; // goodbit==0

// ...
};


What does "goodbit==0" exactly mean?

It means that ios_base::goodbit has the value 0.

The iostate type is a bitmask (which means that it is an integer,
enumeration or a bitset) and there exists a constant of this type named
goodbit with the value 0.

If I were you I'd get myself a copy of the standard or a draft close to
the standard.
 
J

john

Miguel said:
Means literally that everything is ok. 'goodbit' has no bits set and therefore
means that the IO state is not in error.


It is the 0 that made me asking. Does it mean that it is guaranteed that
good() is true when goodbit has the value 0, on all systems? Also does
this apply to the rest iostates, badbit, eofbit, and failbit, that the
OK setting is the value 0?


So, can we just use it in the style:


#include <iostream>

void iocopy()
{
using namespace std;

char c;

while(!cin.goodbit)
{
cin.get(c);
cout<< c;
}[john@localhost src]$ ./foobar-cpp
Before input:
cin.good()= true
cin.goodbit= 0
1
1
1
1
1
1


cin.good()= false
cin.goodbit= 0
[john@localhost src]$

}


int main()
{
iocopy();
}


In my system (Linux) the above code hangs (infinite loop) on EOF
(Ctrl-D), but the code:


#include <iostream>

void iocopy()
{
using namespace std;

char c;

while(cin.good())
{
cin.get(c);
cout<< c;
}
}


int main()
{
iocopy();
}

does not hang.




The code:

#include <iostream>

void iocopy()
{
using namespace std;

char c;

cout<< boolalpha;

cout<< "\ncin.good()= "<< cin.good()<< endl
<< "cin.goodbit= "<< cin.goodbit<< endl
<< "cin.badbit= "<< cin.badbit<< endl
<< "cin.eofbit= "<< cin.eofbit<< endl
<< "cin.failbit= "<< cin.failbit<<endl;

do
{
cin.get(c);
cout<< c;
}while( cin.good() );


cout<< "\ncin.good()= "<< cin.good()<< endl
<< "cin.goodbit= "<< cin.goodbit<< endl
<< "cin.badbit= "<< cin.badbit<< endl
<< "cin.eofbit= "<< cin.eofbit<< endl
<< "cin.failbit= "<< cin.failbit<<endl;
}


int main()
{
iocopy();
}


reveals:

[john@localhost src]$ ./foobar-cpp

cin.good()= true
cin.goodbit= 0
cin.badbit= 1
cin.eofbit= 2
cin.failbit= 4
1
1
1
1


cin.good()= false
cin.goodbit= 0
cin.badbit= 1
cin.eofbit= 2
cin.failbit= 4

[john@localhost src]$



I entered '1' twice from keyboard and then pressed Ctrl-D. My system is
CentOS 5.0 x86.

[john@localhost src]$ g++ -v
Using built-in specs.
Target: i386-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-libgcj-multifile
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada
--enable-java-awt=gtk --disable-dssi --enable-plugin
--with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre
--with-cpu=generic --host=i386-redhat-linux
Thread model: posix
gcc version 4.1.1 20070105 (Red Hat 4.1.1-52)

[john@localhost src]$


Conclusions: In my system, it looks like goodbit is 0 before input and
remains 0 after EOF, the other "*bits" are non-zero before input and
retain their values after EOF, while good() changes after EOF.


Am I missing something here? :)
 
J

john

The message corrected:


It is the 0 that made me asking. Does it mean that it is guaranteed that
good() is true when goodbit has the value 0, on all systems? Also does
this apply to the rest iostates, badbit, eofbit, and failbit, that the
OK setting is the value 0?


So, can we just use it in the style:


#include <iostream>

void iocopy()
{
using namespace std;

char c;

while(!cin.goodbit)
{
cin.get(c);
cout<< c;
}

}


int main()
{
iocopy();
}




In my system (Linux) the above code hangs (infinite loop) on EOF
(Ctrl-D), but the code:


#include <iostream>

void iocopy()
{
using namespace std;

char c;

while(cin.good())
{
cin.get(c);
cout<< c;
}
}


int main()
{
iocopy();
}

does not hang.




The code:

#include <iostream>

void iocopy()
{
using namespace std;

char c;

cout<< boolalpha;

cout<< "\ncin.good()= "<< cin.good()<< endl
<< "cin.goodbit= "<< cin.goodbit<< endl
<< "cin.badbit= "<< cin.badbit<< endl
<< "cin.eofbit= "<< cin.eofbit<< endl
<< "cin.failbit= "<< cin.failbit<<endl;

do
{
cin.get(c);
cout<< c;
}while( cin.good() );


cout<< "\ncin.good()= "<< cin.good()<< endl
<< "cin.goodbit= "<< cin.goodbit<< endl
<< "cin.badbit= "<< cin.badbit<< endl
<< "cin.eofbit= "<< cin.eofbit<< endl
<< "cin.failbit= "<< cin.failbit<<endl;
}


int main()
{
iocopy();
}


reveals:

[john@localhost src]$ ./foobar-cpp

cin.good()= true
cin.goodbit= 0
cin.badbit= 1
cin.eofbit= 2
cin.failbit= 4
1
1
1
1


cin.good()= false
cin.goodbit= 0
cin.badbit= 1
cin.eofbit= 2
cin.failbit= 4

[john@localhost src]$



I entered '1' twice from keyboard and then pressed Ctrl-D. My system is
CentOS 5.0 x86.

[john@localhost src]$ g++ -v
Using built-in specs.
Target: i386-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-libgcj-multifile
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada
--enable-java-awt=gtk --disable-dssi --enable-plugin
--with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre
--with-cpu=generic --host=i386-redhat-linux
Thread model: posix
gcc version 4.1.1 20070105 (Red Hat 4.1.1-52)

[john@localhost src]$


Conclusions: In my system, it looks like goodbit is 0 before input and
remains 0 after EOF, the other "*bits" are non-zero before input and
retain their values after EOF, while good() changes after EOF.


Am I missing something here? :)
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

The message corrected:


It is the 0 that made me asking. Does it mean that it is guaranteed that
good() is true when goodbit has the value 0, on all systems? Also does
this apply to the rest iostates, badbit, eofbit, and failbit, that the
OK setting is the value 0?


So, can we just use it in the style:


#include <iostream>

void iocopy()
{
using namespace std;

char c;

while(!cin.goodbit)
{
cin.get(c);
cout<< c;
}

}


int main()
{
iocopy();
}




In my system (Linux) the above code hangs (infinite loop) on EOF
(Ctrl-D), but the code:


#include <iostream>

void iocopy()
{
using namespace std;

char c;

while(cin.good())
{
cin.get(c);
cout<< c;
}
}


int main()
{
iocopy();
}

does not hang.




The code:

#include <iostream>

void iocopy()
{
using namespace std;

char c;

cout<< boolalpha;

cout<< "\ncin.good()= "<< cin.good()<< endl
<< "cin.goodbit= "<< cin.goodbit<< endl
<< "cin.badbit= "<< cin.badbit<< endl
<< "cin.eofbit= "<< cin.eofbit<< endl
<< "cin.failbit= "<< cin.failbit<<endl;

do
{
cin.get(c);
cout<< c;
}while( cin.good() );


cout<< "\ncin.good()= "<< cin.good()<< endl
<< "cin.goodbit= "<< cin.goodbit<< endl
<< "cin.badbit= "<< cin.badbit<< endl
<< "cin.eofbit= "<< cin.eofbit<< endl
<< "cin.failbit= "<< cin.failbit<<endl;
}


int main()
{
iocopy();
}


reveals:

[john@localhost src]$ ./foobar-cpp

cin.good()= true
cin.goodbit= 0
cin.badbit= 1
cin.eofbit= 2
cin.failbit= 4
1
1
1
1


cin.good()= false
cin.goodbit= 0
cin.badbit= 1
cin.eofbit= 2
cin.failbit= 4

[john@localhost src]$



I entered '1' twice from keyboard and then pressed Ctrl-D. My system is
CentOS 5.0 x86.

[john@localhost src]$ g++ -v
Using built-in specs.
Target: i386-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-libgcj-multifile
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada
--enable-java-awt=gtk --disable-dssi --enable-plugin
--with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre
--with-cpu=generic --host=i386-redhat-linux
Thread model: posix
gcc version 4.1.1 20070105 (Red Hat 4.1.1-52)

[john@localhost src]$


Conclusions: In my system, it looks like goodbit is 0 before input and
remains 0 after EOF, the other "*bits" are non-zero before input and
retain their values after EOF, while good() changes after EOF.


Am I missing something here? :)

goodbit is a constant with the value 0, the fact that it is constant you
should have read from the declaration: static *const* iostate.
 
J

john

Erik said:
goodbit is a constant with the value 0, the fact that it is constant you
should have read from the declaration: static *const* iostate.


Duh, you are right.
 
J

Jerry Coffin

The message corrected:


It is the 0 that made me asking. Does it mean that it is guaranteed that
good() is true when goodbit has the value 0, on all systems?

There is not good bit. basic_ios::good() is defined as returning
'rdstate() == 0;' -- it it returns true if and only if badbit, failbit
and eofbit are all 0.
#include <iostream>

void iocopy()
{
using namespace std;

char c;

while(!cin.goodbit)
{
cin.get(c);
cout<< c;
}

No -- almost every loop of this form is fatally flawed. For this to
work, the eofbit would need to be set as soon as you read the last
character in the file. That's NOT what happens. Instead, the eofbit is
set only when you try to read a character, and the last character in the
file had previously been written.

To work correctly, your loop condition should attempt to read a
character, and immediately check the state after that read. The members
of iostream facilitate this by returning a reference to the stream
object. Thanks to the conversion to void *, you can just treat that as a
boolean value, and it tells you whether you should exit the loop:

while (cin.get(c))
cout << c;

Depending on how you want to handle errors, after the loop has exited,
you may want to check the bits to see which one was set. This will tell
you whether you reached the end of the file normally, or whether there
was some sort of problem while you were trying to read it.
 
J

Jerry Coffin

[ ... ]
No -- almost every loop of this form is fatally flawed. For this to
work, the eofbit would need to be set as soon as you read the last
character in the file. That's NOT what happens. Instead, the eofbit is
set only when you try to read a character, and the last character in the
file had previously been written.

Oops -- that should read "previously been read." Sorry 'bout that.
 
J

James Kanze

On 2007-09-10 16:52, john wrote:

[...]
goodbit is a constant with the value 0, the fact that it is
constant you should have read from the declaration: static
*const* iostate.

Most importantly: despite its name, goodbit is not a bit.
Basically, iostate is a "bitmask" type; an implementation
defined type which can be thought of as a set of bits. badbit,
failbit, and eofbit are constants which, when or'ed with an
iostate, set the corresponding bit. Logically, they can be
thought of as names for the bit, but of course, they too are of
type iostate, corresponding to values with a single bit set.
goodbit is a special value in which has no bits set, which can
be used to say that you don't want any bits set. Thus, in an
operator>>, to set the iostate to failbit, you might write:
dest.clear( std::ios::failbit ) ;
, to set both failbit and eofbit:
dest.clear( std::ios::failbit | std::ios::eofbit ) ;
and to reset all of the bits:
dest.clear( std::ios::goodbit ) ;
(which is the default value of the argument).
 
J

john

James said:
>
Thus, in an
operator>>, to set the iostate to failbit, you might write:
dest.clear( std::ios::failbit ) ;
, to set both failbit and eofbit:
dest.clear( std::ios::failbit | std::ios::eofbit ) ;
and to reset all of the bits:
dest.clear( std::ios::goodbit ) ;
(which is the default value of the argument).


I am still reading the TC++PL3 21 chapter (I think there is a setstate()
explained later on the chapter), however I wonder since the inheritances
are public, why don't we just use

cin.failbit etc instead of ios::failbit etc.
 
J

john

john said:
I am still reading the TC++PL3 21 chapter (I think there is a setstate()
explained later on the chapter), however I wonder since the inheritances
are public, why don't we just use

cin.failbit etc instead of ios::failbit etc.


And if I am not wrong, it is ios_base::failbit and not ios::failbit.
 
P

Pete Becker

I am still reading the TC++PL3 21 chapter (I think there is a
setstate() explained later on the chapter), however I wonder since the
inheritances are public, why don't we just use

cin.failbit etc instead of ios::failbit etc.

Because input often comes from a source other than cin.
ios_base::failbit makes better sense for code that's reading from an
istream&.
 
J

john

Pete said:
Because input often comes from a source other than cin.
ios_base::failbit makes better sense for code that's reading from an
istream&.


I suppose you are talking about the source of the stream and not the
stream itself (e.g. cin has the same source with stdin. cerr, clog have
the same source as stderr, with cerr being unbuffered).

In any case, istream which is basic_istream<char>, always has ios_base
as a base, so all istreams have as public members the failbit, eofbit, etc.
 
F

Frank Birbacher

Hi!
The iostate type is a bitmask (which means that it is an integer,
enumeration or a bitset) and there exists a constant of this type named
goodbit with the value 0.

Is the iostate type guaranteed to be POD?

Frank
 
B

BobR

Erik Wikström wrote in message...
bitset is a container from the standard library and I don't think it is
a POD type.


Unless it was changed when it went into the std C++ lib, it's not a
container.

My old SGI docs state:
" Description
Bitset is very similar to vector<bool> (also known as bit_vector): it
contains a collection of bits, and provides constant-time access to each
bit. There are two main differences between bitset and vector<bool>.
First, the size of a bitset cannot be changed: bitset's template parameter
N, which specifies the number of bits in the bitset, must be an integer
constant.

** Second, bitset is not a Sequence; in fact, it is not an STL Container at
all.**

It does not have iterators, for example, or begin() and end() member
functions. Instead, bitset's interface resembles that of unsigned integers.
It defines bitwise arithmetic operators such as &=, |=, and ^=.
In general, bit 0 is the least significant bit and bit N-1 is the most
significant bit.
"

I don't give a heck what bitsets are, they're fun to play with. <G>
Want an 143 bit integer?
std::bitset<143> OddInt;
<G>
 
J

john

BobR said:
Unless it was changed when it went into the std C++ lib, it's not a
container.


The standard says:

"The template class bitset<N> describes an object that can store a
sequence consisting of a fixed number of bits, N".
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

The standard says:

"The template class bitset<N> describes an object that can store a
sequence consisting of a fixed number of bits, N".

Yes, but it does not fulfil the requirements of a container (the
concept), one of which is to provide iterators. Just to confuse people
even more it is described under section 23.3 Associative Containers.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top