Formatted input interpretation

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • TheDD

    Formatted input interpretation

    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
  • Victor Bazarov

    #2
    Re: Formatted input interpretation

    "TheDD" <pas.d.email@pa s.de.spam.fr> wrote...[color=blue]
    > i'm developping some function to read pbm image files. Somewhere in my[/color]
    code[color=blue]
    > 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[/color]
    "a[color=blue]
    > _number_ coded on a char" but i didn't find it.[/color]

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

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

    No, it's not, really.

    Victor


    Comment

    • Siemel Naran

      #3
      Re: Formatted input interpretation

      "TheDD" <pas.d.email@pa s.de.spam.fr> wrote in message
      news:c85gme$4be $1@news-
      [color=blue]
      > 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).[/color]

      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?


      Comment

      • TheDD

        #4
        Re: Formatted input interpretation

        Siemel Naran wrote:
        [color=blue][color=green]
        >> 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).[/color]
        >
        > 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?[/color]

        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

        Comment

        • Siemel Naran

          #5
          Re: Formatted input interpretation

          "TheDD" <pas.d.email@pa s.de.spam.fr> wrote in message
          news:c8631d$bai $1@news-> Siemel Naran wrote:
          [color=blue][color=green][color=darkred]
          > >> texel_t val;
          > >> while (in >> val)[/color][/color][/color]
          [color=blue][color=green]
          > > If the stream is "25" what will you read. Will these be 2 texel_t[/color][/color]
          objects[color=blue][color=green]
          > > with values 2 and 5? Or will it be one with value "25"? And what will[/color][/color]
          a[color=blue][color=green]
          > > 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?[/color]
          >
          > 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 ;).[/color]

          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::fa ilbit);
          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.


          Comment

          • TheDD

            #6
            Re: Formatted input interpretation

            Siemel Naran wrote:
            [color=blue][color=green][color=darkred]
            >> >> texel_t val;
            >> >> while (in >> val)[/color][/color]
            >[color=green][color=darkred]
            >> > If the stream is "25" what will you read. Will these be 2 texel_t[/color][/color]
            > objects[color=green][color=darkred]
            >> > with values 2 and 5? Or will it be one with value "25"? And what will[/color][/color]
            > a[color=green][color=darkred]
            >> > 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?[/color]
            >>
            >> 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 ;).[/color]
            >
            > 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.[/color]

            Sounds great :)
            [color=blue]
            > To make it clear make texexl_t a class so that you can overload operator>>[/color]

            hu... a lot less
            [color=blue]
            > 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::fa ilbit);
            > else e.d_value = (unsigned char)(value);
            > return i;
            > }[/color]

            it looks like a rocket launcher to kill the bug...
            [color=blue]
            > 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.[/color]

            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++.
            [color=blue]
            > There was a post on this NG in the last few days about how to convert an
            > array of chars into an integer.[/color]

            Thx i know how to do that :)

            --
            TheDD

            Comment

            • Siemel Naran

              #7
              Re: Formatted input interpretation

              "TheDD" <pas.d.email@pa s.de.spam.fr> wrote in message
              news:c8649a$6eb $1@news-[color=blue]
              > Siemel Naran wrote:[/color]
              [color=blue][color=green]
              > > 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::fa ilbit);
              > > else e.d_value = (unsigned char)(value);
              > > return i;
              > > }[/color]
              >
              > it looks like a rocket launcher to kill the bug...[/color]

              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::fa ilbit);
              else e = (unsigned char)(value);
              }

              But the class version is only 8 lines more.

              [color=blue][color=green]
              > > But the use of istream >> int is still quite expensive because it[/color][/color]
              handles[color=blue][color=green]
              > > 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[/color][/color]
              manually.[color=blue]
              >
              > Well i would like a way to do it transparently, i was hopping for a self
              > made manipulator but it's not possible.[/color]

              What do you mean by "transparently" ?


              Comment

              • TheDD

                #8
                Re: Formatted input interpretation

                On Sat, 15 May 2004 22:16:02 GMT, Siemel Naran wrote:
                [color=blue][color=green][color=darkred]
                >>> 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::fa ilbit);
                >>> else e.d_value = (unsigned char)(value);
                >>> return i;
                >>> }[/color]
                >>
                >> it looks like a rocket launcher to kill the bug...[/color]
                >
                > Fair enough, but maybe it's because the style is new. You could do[/color]

                the style is new?
                [color=blue]
                > inline
                > void read_excel(std: :istream& i, exel& e) {
                > unsigned value;
                > i >> value;
                > if (i >= 1<CHAR_BIT) e.clear(ios::fa ilbit);
                > else e = (unsigned char)(value);
                > }
                >
                > But the class version is only 8 lines more.[/color]

                true, but i meaned that it's just "hidding the hack behind a
                function". I thank you for your code anyway.
                [color=blue][color=green][color=darkred]
                >>> But the use of istream >> int is still quite expensive because it[/color][/color]
                > handles[color=green][color=darkred]
                >>> 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[/color][/color]
                > manually.[color=green]
                >>
                >> Well i would like a way to do it transparently, i was hopping for a self
                >> made manipulator but it's not possible.[/color]
                >
                > What do you mean by "transparently" ?[/color]

                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

                Comment

                Working...