Formatted input interpretation

T

TheDD

Hello,

i'm developping some function to read pbm image files. Somewhere in my code
i have:

texel_t val;

while (in >> val)
{
...
}

the problem is that since the "real" type of texel_t is unsigned char, so
the my input is 48 instead of 0 (a character is read instead of a small
number).

I was hopping for some kind of manipulator to force the interpretation to "a
_number_ coded on a char" but i didn't find it.

What if the texel_t type was a template parameter, how can i force the
interpretation, if possible?

Right now, i'm using a temporary int value, but it's a hack :(

TIA for your time
 
V

Victor Bazarov

TheDD said:
i'm developping some function to read pbm image files. Somewhere in my code
i have:

texel_t val;

while (in >> val)
{
...
}

the problem is that since the "real" type of texel_t is unsigned char, so
the my input is 48 instead of 0 (a character is read instead of a small
number).

I was hopping for some kind of manipulator to force the interpretation to "a
_number_ coded on a char" but i didn't find it.

If you're reading one digit, then simply subtract '0' from the result...
What if the texel_t type was a template parameter, how can i force the
interpretation, if possible?

You'd need to specialise your functions for 'char' and others and make
the behaviour differ depending on the type.
Right now, i'm using a temporary int value, but it's a hack :(

No, it's not, really.

Victor
 
S

Siemel Naran

texel_t val;

while (in >> val)
{
...
}

the problem is that since the "real" type of texel_t is unsigned char, so
the my input is 48 instead of 0 (a character is read instead of a small
number).

If the stream is "25" what will you read. Will these be 2 texel_t objects
with values 2 and 5? Or will it be one with value "25"? And what will a
stream of "257" read into? Will it be 3 texel_t objects? Or will it be one
which puts the stream into a fail state because of an overflow?
 
T

TheDD

Siemel said:
If the stream is "25" what will you read. Will these be 2 texel_t objects
with values 2 and 5? Or will it be one with value "25"? And what will a
stream of "257" read into? Will it be 3 texel_t objects? Or will it be
one which puts the stream into a fail state because of an overflow?

What i would like is:

"25" -> 1 texel_t with value 25
"257" -> fail state

I've forget to say that in pbm (P1) files, the color is white (0) or black
(1). But the question is good for future extensions (and c++ knowledge ;).
 
S

Siemel Naran

What i would like is:

"25" -> 1 texel_t with value 25
"257" -> fail state

I've forget to say that in pbm (P1) files, the color is white (0) or black
(1). But the question is good for future extensions (and c++ knowledge ;).

Easiest way is to read an unsigned integer, check if it is more than 255 and
if so set the failbit, then cast to an unsigned char.

To make it clear make texexl_t a class so that you can overload operator>>
for it, and ideally you'll suffer no performance overhead because the
compiler would optimize texcel_t as if it were an unsigned integer.

class exel_t {
public:
excel_t() { }
unsigned char value() const { return d_value; }
private:
unsigned char d_value;
};

inline
std::istream& operator<<(std::istream& i, exel& e) {
unsigned value;
i >> value;
if (i >= 1<CHAR_BIT) e.clear(ios::failbit);
else e.d_value = (unsigned char)(value);
return i;
}

But the use of istream >> int is still quite expensive because it handles
sentries, does locale dependent formatting, etc. There are alternative
solutions available. One is to use fscanf. Another is to get the
underlying streambuf with i.rdbuf() and parse the chars yourself manually.
There was a post on this NG in the last few days about how to convert an
array of chars into an integer.
 
T

TheDD

Siemel said:
Easiest way is to read an unsigned integer, check if it is more than 255
and if so set the failbit, then cast to an unsigned char.

Sounds great :)
To make it clear make texexl_t a class so that you can overload operator>>

hu... a lot less
for it, and ideally you'll suffer no performance overhead because the
compiler would optimize texcel_t as if it were an unsigned integer.

class exel_t {
public:
excel_t() { }
unsigned char value() const { return d_value; }
private:
unsigned char d_value;
};

inline
std::istream& operator<<(std::istream& i, exel& e) {
unsigned value;
i >> value;
if (i >= 1<CHAR_BIT) e.clear(ios::failbit);
else e.d_value = (unsigned char)(value);
return i;
}

it looks like a rocket launcher to kill the bug...
But the use of istream >> int is still quite expensive because it handles
sentries, does locale dependent formatting, etc. There are alternative
solutions available. One is to use fscanf. Another is to get the
underlying streambuf with i.rdbuf() and parse the chars yourself manually.

Well i would like a way to do it transparently, i was hopping for a self
made manipulator but it's not possible.

I think it's a lack in c++.
There was a post on this NG in the last few days about how to convert an
array of chars into an integer.

Thx i know how to do that :)
 
S

Siemel Naran

TheDD said:
Siemel Naran wrote:

it looks like a rocket launcher to kill the bug...

Fair enough, but maybe it's because the style is new. You could do

inline
void read_excel(std::istream& i, exel& e) {
unsigned value;
i >> value;
if (i >= 1<CHAR_BIT) e.clear(ios::failbit);
else e = (unsigned char)(value);
}

But the class version is only 8 lines more.

manually.

Well i would like a way to do it transparently, i was hopping for a self
made manipulator but it's not possible.

What do you mean by "transparently"?
 
T

TheDD

Fair enough, but maybe it's because the style is new. You could do

the style is new?
inline
void read_excel(std::istream& i, exel& e) {
unsigned value;
i >> value;
if (i >= 1<CHAR_BIT) e.clear(ios::failbit);
else e = (unsigned char)(value);
}

But the class version is only 8 lines more.

true, but i meaned that it's just "hidding the hack behind a
function". I thank you for your code anyway.
What do you mean by "transparently"?

well, with, 1 or 2 tokens, and without a need of specializing the
template if it was one (it will probably be).Something "classy" ;)
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top