By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,278 Members | 1,142 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,278 IT Pros & Developers. It's quick & easy.

Better way to use istream to read an ascii value into a char.

P: n/a
In one of my files I am outputting the value of a char into a human readable
file. That is,
char a = 123;
std::ofstream CharFile( ("Players\\" + Name + ".char").c_str());
if ( CharFile.is_open() )
CharFile << (int) a;

So the file has the character a stored as "123".

That was the easy part, now comes the fun of reading it back into the char.

I tried a number of things and finally wound up doing this:

std::istream& operator >>( std::istream& is, char& Byte )
{
int temp;
is >> temp;
Byte = temp;
return is;
}

char a;
std::ifstream CharFile( ( "Players\\" + CharName + ".char" ).c_str());
if ( CharFile.is_open() )
CharFile >> a;

You may wonder why I did that instead of just directly reading it into a
temp int directly and assigning, the reason being I'm writing many of these
to the file.

is >> CChar.GM >> CChar.GMLevel >> CChar.Banned >> CChar.Jailed >>
CChar.Muted >>
CChar.MessageRange >> CChar.Avatar >> CChar.Map >> CChar.Pos.x >>
CChar.Pos.y >>
CChar.Pos.z >> CChar.X_Degrees >> CChar.Race >> CChar.Vigor >>
CChar.Fortitude >>
CChar.Coordination >> CChar.Agility >> CChar.Reason >> CChar.Perception >>
CChar.Willpower >> CChar.Psychic >> CChar.Charisma >> CChar.Affinity >>
CChar.AffinityAir >> CChar.AffinityWater >> CChar.AffinityFire >>
CChar.AffinityEarth >> CChar.Sin;

If I had to break this up into different calls it would be, in my opionion,
harder to maintain.

The thing I don't like about overriding the operator >> for a char, though,
is if I ever want to actually write a char as a byte itself (which I don't
think I will).

I'm just wondering if there is a better way.

I attempted something along the lines of:

std::istream& ReadByteVal( std::istream& is, char& Byte ) {/**/}

and then attempted to use it like

is >> ReadByteVal( is, CChar.Agility ) >> ReadByteVal( is, CChar.Reason ) >>
/**/

but that wouldn't compile, the compiler complaining something about not
finding a call taking an rvalue.

Someone else came up with a horrible looking template that seems to be prone
to errors itself. Anyone have any ideas?
May 4 '06 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Jim Langston wrote:
In one of my files I am outputting the value of a char into a human readable
file. That is,
char a = 123;
std::ofstream CharFile( ("Players\\" + Name + ".char").c_str());
if ( CharFile.is_open() )
CharFile << (int) a;

So the file has the character a stored as "123".

That was the easy part, now comes the fun of reading it back into the char.

I tried a number of things and finally wound up doing this:

std::istream& operator >>( std::istream& is, char& Byte )
{
int temp;
is >> temp;
Byte = temp;
return is;
}

char a;
std::ifstream CharFile( ( "Players\\" + CharName + ".char" ).c_str());
if ( CharFile.is_open() )
CharFile >> a;

You may wonder why I did that instead of just directly reading it into a
temp int directly and assigning, the reason being I'm writing many of these
to the file.

is >> CChar.GM >> CChar.GMLevel >> CChar.Banned >> CChar.Jailed >>
CChar.Muted >>
CChar.MessageRange >> CChar.Avatar >> CChar.Map >> CChar.Pos.x >>
CChar.Pos.y >>
CChar.Pos.z >> CChar.X_Degrees >> CChar.Race >> CChar.Vigor >>
CChar.Fortitude >>
CChar.Coordination >> CChar.Agility >> CChar.Reason >> CChar.Perception >>
CChar.Willpower >> CChar.Psychic >> CChar.Charisma >> CChar.Affinity >>
CChar.AffinityAir >> CChar.AffinityWater >> CChar.AffinityFire >>
CChar.AffinityEarth >> CChar.Sin;

If I had to break this up into different calls it would be, in my opionion,
harder to maintain.

The thing I don't like about overriding the operator >> for a char, though,
is if I ever want to actually write a char as a byte itself (which I don't
think I will).

I'm just wondering if there is a better way.

I attempted something along the lines of:

std::istream& ReadByteVal( std::istream& is, char& Byte ) {/**/}

and then attempted to use it like

is >> ReadByteVal( is, CChar.Agility ) >> ReadByteVal( is, CChar.Reason ) >>
/**/

but that wouldn't compile, the compiler complaining something about not
finding a call taking an rvalue.

Someone else came up with a horrible looking template that seems to be prone
to errors itself. Anyone have any ideas?


Any easy way would be to make your own stream:

class my_stream
{
public:
my_stream(const std::string& fn)
: ifs_(fn.c_str())
{
}

char read_byte()
{
int i = 0;
ifs_ >> i;
char c = i;
return c;
}

private:
std::ifstream ifs_;
};

my_stream& operator>>(my_stream& s, char& c)
{
c = s.read_byte();
return s;
}

int main()
{
my_stream s("test");
char c;
s >> c;
}

Deriving from std::*istream or aggregating one depends on your design.
Jonathan

May 4 '06 #2

P: n/a
Jim Langston wrote:
In one of my files I am outputting the value of a char into a human readable
file. That is,
char a = 123;
std::ofstream CharFile( ("Players\\" + Name + ".char").c_str());
if ( CharFile.is_open() )
CharFile << (int) a;

So the file has the character a stored as "123".

That was the easy part, now comes the fun of reading it back into the char.

I tried a number of things and finally wound up doing this:

std::istream& operator >>( std::istream& is, char& Byte )
{
int temp;
is >> temp;
Byte = temp;
return is;
}

char a;
std::ifstream CharFile( ( "Players\\" + CharName + ".char" ).c_str());
if ( CharFile.is_open() )
CharFile >> a;
[snip]
The thing I don't like about overriding the operator >> for a char, though,
is if I ever want to actually write a char as a byte itself (which I don't
think I will).

I'm just wondering if there is a better way.

I attempted something along the lines of:

std::istream& ReadByteVal( std::istream& is, char& Byte ) {/**/}

and then attempted to use it like

is >> ReadByteVal( is, CChar.Agility ) >> ReadByteVal( is, CChar.Reason ) >>
/**/

but that wouldn't compile, the compiler complaining something about not
finding a call taking an rvalue.

Someone else came up with a horrible looking template that seems to be prone
to errors itself. Anyone have any ideas?


Wrap a char reference in a user defined type and define operator>> for
this type:

#include <iostream>

struct achar
{
achar(char &c) : c_(c) {}
char &c_;
};

std::istream &
operator>>(std::istream &is, achar a)
{
int tmp;
is >> tmp;
a.c_ = tmp;
return is;
}

int
main()
{
char c;
std::cin >> achar(c);
std::cout << c << std::endl;
}

May 4 '06 #3

P: n/a
"Markus Schoder" <a3*************@yahoo.de> wrote in message
news:11**********************@y43g2000cwc.googlegr oups.com...
Jim Langston wrote:
In one of my files I am outputting the value of a char into a human
readable
file. That is,
char a = 123;
std::ofstream CharFile( ("Players\\" + Name + ".char").c_str());
if ( CharFile.is_open() )
CharFile << (int) a;

So the file has the character a stored as "123".

That was the easy part, now comes the fun of reading it back into the
char.

I tried a number of things and finally wound up doing this:

std::istream& operator >>( std::istream& is, char& Byte )
{
int temp;
is >> temp;
Byte = temp;
return is;
}

char a;
std::ifstream CharFile( ( "Players\\" + CharName + ".char" ).c_str());
if ( CharFile.is_open() )
CharFile >> a;
[snip]
The thing I don't like about overriding the operator >> for a char,
though,
is if I ever want to actually write a char as a byte itself (which I
don't
think I will).

I'm just wondering if there is a better way.


<snip>
Wrap a char reference in a user defined type and define operator>> for
this type:

#include <iostream>

struct achar
{
achar(char &c) : c_(c) {}
char &c_;
};

std::istream &
operator>>(std::istream &is, achar a)
{
int tmp;
is >> tmp;
a.c_ = tmp;
return is;
}

int
main()
{
char c;
std::cin >> achar(c);
std::cout << c << std::endl;
}


Ahh, perfect, thanks! I'm sure you meant
std::istream &
operator>>(std::istream &is, achar& a)
May 6 '06 #4

P: n/a

"Jim Langston" <ta*******@rocketmail.com> wrote in message
news:P0**************@fe04.lga...
"Markus Schoder" <a3*************@yahoo.de> wrote in message
news:11**********************@y43g2000cwc.googlegr oups.com...

[big snip]
Wrap a char reference in a user defined type and define operator>> for
this type:

#include <iostream>

struct achar
{
achar(char &c) : c_(c) {}
char &c_;
};

std::istream &
operator>>(std::istream &is, achar a)
{
int tmp;
is >> tmp;
a.c_ = tmp;
return is;
}

int
main()
{
char c;
std::cin >> achar(c);
std::cout << c << std::endl;
}


Ahh, perfect, thanks! I'm sure you meant
std::istream &
operator>>(std::istream &is, achar& a)


I guess I was wrong on this. I tried it with the achar& a and the compiler
warned about converting an achar a to an achar& a on a non constant
variable. So I put it the way you had it and it seems to work (compiled,
only one warning about achar not being able to have an assigment oporator
generated) but not tested. Thanks again.
May 6 '06 #5

P: n/a
Jim Langston wrote:
"Jim Langston" <ta*******@rocketmail.com> wrote in message
news:P0**************@fe04.lga...
"Markus Schoder" <a3*************@yahoo.de> wrote in message
news:11**********************@y43g2000cwc.googlegr oups.com... [big snip]
Wrap a char reference in a user defined type and define operator>> for
this type:

#include <iostream>

struct achar
{
achar(char &c) : c_(c) {}
char &c_;
};

std::istream &
operator>>(std::istream &is, achar a)
{
int tmp;
is >> tmp;
a.c_ = tmp;
return is;
}

int
main()
{
char c;
std::cin >> achar(c);
std::cout << c << std::endl;
}


Ahh, perfect, thanks! I'm sure you meant
std::istream &
operator>>(std::istream &is, achar& a)


I guess I was wrong on this.


Note that achar takes the char by reference, not by value. So whether
achar itself is passed by value or reference does not matter.
I tried it with the achar& a and the compiler
warned about converting an achar a to an achar& a on a non constant
variable.


In the statement

std::cin >> achar(c);

"achar(c)" constructs an rvalue which cannot be bound to a non-const
reference. You must either pass it by value or by const reference.
Jonathan

May 6 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.