Formatted input interpretation

Discussion in 'C++' started by TheDD, May 15, 2004.

  1. TheDD

    TheDD Guest

    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

    --
    TheDD
     
    TheDD, May 15, 2004
    #1
    1. Advertising

  2. "TheDD" <> wrote...
    > 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
     
    Victor Bazarov, May 15, 2004
    #2
    1. Advertising

  3. TheDD

    Siemel Naran Guest

    "TheDD" <> wrote in message
    news:c85gme$4be$1@news-

    > 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?
     
    Siemel Naran, May 15, 2004
    #3
  4. TheDD

    TheDD Guest

    Siemel Naran wrote:

    >> 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?


    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 ;).

    --
    TheDD
     
    TheDD, May 15, 2004
    #4
  5. TheDD

    Siemel Naran Guest

    "TheDD" <> wrote in message
    news:c8631d$bai$1@news-> Siemel Naran wrote:

    > >> texel_t val;
    > >> while (in >> val)


    > > 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 ;).


    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.
     
    Siemel Naran, May 15, 2004
    #5
  6. TheDD

    TheDD Guest

    Siemel Naran wrote:

    >> >> texel_t val;
    >> >> while (in >> val)

    >
    >> > 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 ;).

    >
    > 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 :)

    --
    TheDD
     
    TheDD, May 15, 2004
    #6
  7. TheDD

    Siemel Naran Guest

    "TheDD" <> wrote in message
    news:c8649a$6eb$1@news-
    > Siemel Naran wrote:


    > > 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...


    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.


    > > 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.


    What do you mean by "transparently"?
     
    Siemel Naran, May 15, 2004
    #7
  8. TheDD

    TheDD Guest

    On Sat, 15 May 2004 22:16:02 GMT, Siemel Naran wrote:

    >>> 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...

    >
    > 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.

    >>> 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.

    >
    > 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" ;)

    --
    TheDD
     
    TheDD, May 15, 2004
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Matt
    Replies:
    3
    Views:
    457
    Eric Reitmaier
    Oct 19, 2004
  2. TheDD
    Replies:
    4
    Views:
    533
    John Harrison
    May 13, 2004
  3. dkk

    formatted input/output question

    dkk, Apr 10, 2006, in forum: C Programming
    Replies:
    2
    Views:
    336
    Herbert Rosenau
    Apr 12, 2006
  4. Jason Heyes
    Replies:
    0
    Views:
    280
    Jason Heyes
    Jun 24, 2005
  5. Deep

    Formatted Input

    Deep, Mar 10, 2007, in forum: Python
    Replies:
    1
    Views:
    326
    Frank
    Mar 10, 2007
Loading...

Share This Page