The problem is that the >>
operator for a string
(std::string
or a C style string) actually implements the
semantics for a word, with a particular definition of word. The
decision is arbitrary (I would have made it a line), but since
a string can represent many different things, they had to choose
something.
The solution, in general, is not to use >>
on a string, ever.
Define the class you want (here, probably something like
Symbol
), and define an operator >>
for it which respects its
semantics. You're code will be a lot clearer for it, and you
can add various invarant controls as appropriate. If you know
that the field is always exactly four characters, you can do
something simple like:
class DContactSymbol
{
char myName[ 4 ];
public:
// ...
friend std::istream&
operator>>( std::istream& source, DContactSymbol& dest );
// ...
};
std::istream&
operator>>( std::istream& source, DContactSymbol& dest )
{
std::sentry guard( source );
if ( source ) {
std::string tmp;
std::streambuf* sb = source.rdbuf();
int ch = sb->sgetc();
while ( source && (isalnum( ch ) || ch == '_') ) {
tmp += static_cast< char >( ch );
if ( tmp.size() > sizeof( dest.myName ) ) {
source.setstate( std::ios_base::failbit );
}
}
if ( ch == source::traits_type::eof() ) {
source.setstate( std::ios_base::eofbit );
}
if ( tmp.size() != sizeof( dest.myName ) ) {
source.setstate( std::ios_base::failbit );
}
if ( source ) {
tmp.copy( dest.myName, sizeof( dest.myName ) );
}
}
return source;
}
(Note that unlike some of the other suggestions, for example
using std::istream::read
, this one maintains all of the usual
conventions, like skipping leading white space dependent on the
skipws
flag.)
Of course, if you can't guarantee 100% that the symbol will
always be 4 characters, you should use std::string
for it, and
modify the >>
operator accordingly.
And BTW, you seem to want to read four characters into
dcontact
, although it's only large enough for three (since
>>
will insert a terminating '\0'
). If you read any more
than three into it, you have undefined behavior.