Another help on fstream

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

    #1

    Another help on fstream

    Hello,

    I am trying to take advantage of the formatted ouput operator of
    ostream to rewrite this piece of code /more nicely/:

    oftream fp("/tmp/foo", std::ios::out | std::ios::binar y);
    uint32_t v = 38;
    void* ptr = &v;
    fp.write ( (char*)ptr,(siz e_t)4 );

    Unfortunately I cannot find a way to use '<<'.

    Any idea ?
    Thanks
    Mathieu
  • Victor Bazarov

    #2
    Re: Another help on fstream

    "Mathieu Malaterre" <malatNOSP@Mfre e.fr> wrote...[color=blue]
    > I am trying to take advantage of the formatted ouput operator of ostream
    > to rewrite this piece of code /more nicely/:
    >
    > oftream fp("/tmp/foo", std::ios::out | std::ios::binar y);
    > uint32_t v = 38;
    > void* ptr = &v;
    > fp.write ( (char*)ptr,(siz e_t)4 );
    >
    > Unfortunately I cannot find a way to use '<<'.
    >
    > Any idea ?[/color]

    What's your intent? The code as written outputs four bytes
    that represent your 'uint32_t' value. Each byte is output without
    change, without formatting. That's _binary_ output. Operator <<
    is _formatted_ output. They are generally not interchangeable .
    If you opened the stream for binary output, use binary output means.

    V


    Comment

    • Mathieu Malaterre

      #3
      Re: Another help on fstream

      Victor Bazarov wrote:[color=blue]
      > "Mathieu Malaterre" <malatNOSP@Mfre e.fr> wrote...
      >[color=green]
      >> I am trying to take advantage of the formatted ouput operator of ostream
      >>to rewrite this piece of code /more nicely/:
      >>
      >> oftream fp("/tmp/foo", std::ios::out | std::ios::binar y);
      >> uint32_t v = 38;
      >> void* ptr = &v;
      >> fp.write ( (char*)ptr,(siz e_t)4 );
      >>
      >> Unfortunately I cannot find a way to use '<<'.
      >>
      >>Any idea ?[/color]
      >
      >
      > What's your intent? The code as written outputs four bytes
      > that represent your 'uint32_t' value. Each byte is output without
      > change, without formatting. That's _binary_ output. Operator <<
      > is _formatted_ output. They are generally not interchangeable .
      > If you opened the stream for binary output, use binary output means.[/color]

      Alright,

      I wan't clear, let's rephrase this. The previous code is clearly
      unreadable and any decent compiler should refuse to compile such an ugly
      code. I am trying to find a way to rewrite those 3 ugly lines in a more
      c++ like approach.
      My first attempt was:

      ostream& operator<<( ostream& o, const uint32_t& f )
      {
      void *p = &f;
      o.write( (char*) p, sizeof(4) );
      }

      But this create conflict when used, I am not sure why. Does this mean I
      should rewrite a wrapper around ostream/fstream to handle: uint32_t,
      uint16_t and uint8_t.

      Thanks
      Mathieu

      Comment

      • Victor Bazarov

        #4
        Re: Another help on fstream

        "Mathieu Malaterre" <malatNOSP@Mfre e.fr> wrote...[color=blue]
        > Victor Bazarov wrote:[color=green]
        >> "Mathieu Malaterre" <malatNOSP@Mfre e.fr> wrote...
        >>[color=darkred]
        >>> I am trying to take advantage of the formatted ouput operator of
        >>> ostream to rewrite this piece of code /more nicely/:
        >>>
        >>> oftream fp("/tmp/foo", std::ios::out | std::ios::binar y);
        >>> uint32_t v = 38;
        >>> void* ptr = &v;
        >>> fp.write ( (char*)ptr,(siz e_t)4 );
        >>>
        >>> Unfortunately I cannot find a way to use '<<'.
        >>>
        >>>Any idea ?[/color]
        >>
        >>
        >> What's your intent? The code as written outputs four bytes
        >> that represent your 'uint32_t' value. Each byte is output without
        >> change, without formatting. That's _binary_ output. Operator <<
        >> is _formatted_ output. They are generally not interchangeable .
        >> If you opened the stream for binary output, use binary output means.[/color]
        >
        > Alright,
        >
        > I wan't clear, let's rephrase this. The previous code is clearly
        > unreadable and any decent compiler should refuse to compile such an ugly
        > code. I am trying to find a way to rewrite those 3 ugly lines in a more
        > c++ like approach.
        > My first attempt was:
        >
        > ostream& operator<<( ostream& o, const uint32_t& f )
        > {
        > void *p = &f;
        > o.write( (char*) p, sizeof(4) );
        > }
        >
        > But this create conflict when used, I am not sure why.[/color]

        Probably because your 'uint32_t' is one of the fundamental types for
        which there is already the output operator defined.
        [color=blue]
        > Does this mean I should rewrite a wrapper around ostream/fstream to
        > handle: uint32_t, uint16_t and uint8_t.[/color]

        I don't think so.

        I think, Mathieu, you're a bit confused about what is and what isn't "C++".
        Once again, operator<< and operator>> as far as streams are concerned are
        _formatted_ output and input, respectively. Making them _non-formatted_
        is like overloading ++ and make it decrement. Is there a point to this?

        V


        Comment

        • John Harrison

          #5
          Re: Another help on fstream


          "Mathieu Malaterre" <malatNOSP@Mfre e.fr> wrote in message
          news:t9Efd.4092 7$l07.13931@twi ster.nyroc.rr.c om...[color=blue]
          > Victor Bazarov wrote:[color=green]
          >> "Mathieu Malaterre" <malatNOSP@Mfre e.fr> wrote...
          >>[color=darkred]
          >>> I am trying to take advantage of the formatted ouput operator of
          >>> ostream to rewrite this piece of code /more nicely/:
          >>>
          >>> oftream fp("/tmp/foo", std::ios::out | std::ios::binar y);
          >>> uint32_t v = 38;
          >>> void* ptr = &v;
          >>> fp.write ( (char*)ptr,(siz e_t)4 );
          >>>
          >>> Unfortunately I cannot find a way to use '<<'.
          >>>
          >>>Any idea ?[/color]
          >>
          >>
          >> What's your intent? The code as written outputs four bytes
          >> that represent your 'uint32_t' value. Each byte is output without
          >> change, without formatting. That's _binary_ output. Operator <<
          >> is _formatted_ output. They are generally not interchangeable .
          >> If you opened the stream for binary output, use binary output means.[/color]
          >
          > Alright,
          >
          > I wan't clear, let's rephrase this. The previous code is clearly
          > unreadable and any decent compiler should refuse to compile such an ugly
          > code. I am trying to find a way to rewrite those 3 ugly lines in a more
          > c++ like approach.
          > My first attempt was:
          >
          > ostream& operator<<( ostream& o, const uint32_t& f )
          > {
          > void *p = &f;
          > o.write( (char*) p, sizeof(4) );
          > }
          >
          > But this create conflict when used, I am not sure why. Does this mean I
          > should rewrite a wrapper around ostream/fstream to handle: uint32_t,
          > uint16_t and uint8_t.
          >
          > Thanks
          > Mathieu[/color]

          Here's 'more C++' like approach using templates.

          template <class T>
          ostream& binary_write(os tream& os, const T& val)
          {
          return os.write(reinte rpret_cast<cons t char*>(&val), sizeof val);
          }

          template <>
          ostream& binary_write(os tream& os, const char* val)
          {
          return os.write(val, strlen(val));
          }

          ofstream fp("/tmp/foo", std::ios::out | std::ios::binar y);
          binary_write(fp , 38);

          binary_write(fp , 42);
          double x = 1.234;
          binary_write(fp , x);

          But this is a slight risky since you can use it with non-POD types which
          would get you into trouble. E.g.

          string y = "abc";
          binary_write(fp , y);

          That would compile but not do anything sensible.

          I agree with Victor's comments about <<, you shouldn't be trying to overload
          that for binary output, that is just too confusing. I would stick with
          functions.

          All code is untested.

          john


          Comment

          Working...