Manipulator question...

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

    Manipulator question...


    When I use an iostream manipulator in a cout statement, it seems to affect
    all subsequent cout statements.

    cout << x << endl; // dec by default
    cout << hex << x << endl; // hex
    cout << x << endl // still hex

    Is there a way I can have manipulators affect only the "current" cout
    statement?


  • Pete Becker

    #2
    Re: Manipulator question...

    barcaroller wrote:
    When I use an iostream manipulator in a cout statement, it seems to affect
    all subsequent cout statements.
    >
    cout << x << endl; // dec by default
    cout << hex << x << endl; // hex
    cout << x << endl // still hex
    >
    Is there a way I can have manipulators affect only the "current" cout
    statement?
    >
    Save the stream's formatting flags, manipulate it, and when you're done,
    restore the flags. For that you'll need to read about the
    ios_base::flags functions.

    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)

    Comment

    • BobR

      #3
      Re: Manipulator question...


      barcaroller <barcaroller@mu sic.netwrote in message...
      >
      When I use an iostream manipulator in a cout statement, it seems to affect
      all subsequent cout statements.
      >
      cout << x << endl; // dec by default
      cout << hex << x << endl; // hex
      cout << x << endl // still hex
      >
      Is there a way I can have manipulators affect only the "current" cout
      statement?
      What Pete said.
      But, for a few dollars more, there is another way:

      { // main or function
      { // scope1
      std::ostringstr eam sos;
      sos << x << endl; // dec by default
      sos << hex << x << endl; // hex
      cout << sos.str() <<endl;
      } // scope1
      cout << x << endl; // as normal (default)
      }

      Now you are not changing std::cout.
      In case you can't do that, here is a short example:

      { // main of func
      std::ios_base:: fmtflags oldFlg =
      cout.setf(std:: ios_base::fixed , std::ios::float field);
      int OutPre = cout.precision( 40); // save prec, change to 40
      // ------- use it here
      // Case2Com Case2;
      // Case2.execute(c out);
      // -------
      cout.setf( oldFlg, std::ios::float field ); // reset what you need
      cout.precision( OutPre ); // restore orig precision
      }

      Here you pay another price, you need to 'reset' everything you changed.
      Notice that using the stringstream way (in a scope), you do not need to
      'reset' it, just let it go out of scope (destruct).

      --
      Bob R
      POVrookie


      Comment

      • James Kanze

        #4
        Re: Manipulator question...

        On May 24, 7:21 pm, "BobR" <removeBadB...@ worldnet.att.ne twrote:
        barcaroller <barcarol...@mu sic.netwrote in message...
        When I use an iostream manipulator in a cout statement, it seems to affect
        all subsequent cout statements.
        cout << x << endl; // dec by default
        cout << hex << x << endl; // hex
        cout << x << endl // still hex
        Is there a way I can have manipulators affect only the "current" cout
        statement?
        What Pete said.
        But, for a few dollars more, there is another way:
        { // main or function
        { // scope1
        std::ostringstr eam sos;
        sos << x << endl; // dec by default
        sos << hex << x << endl; // hex
        cout << sos.str() <<endl;} // scope1
        >
        cout << x << endl; // as normal (default)
        }
        Now you are not changing std::cout.
        That's definitly the most certain. On the other hand, it's a
        lot of extra effort, and rather heavy and cumbersome.
        In case you can't do that, here is a short example:
        { // main of func
        std::ios_base:: fmtflags oldFlg =
        cout.setf(std:: ios_base::fixed , std::ios::float field);
        int OutPre = cout.precision( 40); // save prec, change to 40
        // ------- use it here
        // Case2Com Case2;
        // Case2.execute(c out);
        // -------
        cout.setf( oldFlg, std::ios::float field ); // reset what you need
        cout.precision( OutPre ); // restore orig precision
        }
        Here you pay another price, you need to 'reset' everything you changed.
        This doesn't solve the problem. What happens if there is an
        exception when you are using it? I thought everyone used RAII
        here, and had their own SaveFormat or whatever class, so that
        you'd write:

        SaveFormat saver( std::cout ) ;
        // whatever...

        and when the destructor of saver was called, the original format
        would be restored.

        It's probably also worth pointing out that it is relatively
        simple to use classes as manipulators, and restore the format in
        their destructor. And of course, that in general, you don't use
        the standard manipulators much in application code anyway; you
        define your own, with application specific semantics, and do
        logical formatting, instead of physical. (That way, when
        someone decides that you need to output an additional digit in
        degrees, you just change the manipulator for degrees, rather
        than having to find which setprecision in you code refer to
        degrees, and which don't.)

        I have examples of both IOSave (a very, very old format saver)
        and some useful manipulators (FFmt, EFmt and HexFmt) which
        restore state at the end of the full expression at my site
        (http://kanze.james.neuf.fr/code-en.html; the above mentionned
        classes are in the IO subsystem).

        --
        James Kanze (GABI Software) email:james.kan ze@gmail.com
        Conseils en informatique orientée objet/
        Beratung in objektorientier ter Datenverarbeitu ng
        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

        Comment

        • BobR

          #5
          Re: Manipulator question...


          James Kanze <james.kanze@gm ail.comwrote in message ...

          /* """
          On May 24, 7:21 pm, "BobR" wrote:
          What Pete said.
          But, for a few dollars more, there is another way:
          { // scope1
          std::ostringstr eam sos;
          sos << hex << x << endl; // hex
          cout << sos.str() <<endl;} // scope1
          Now you are not changing std::cout.
          That's definitly the most certain. On the other hand, it's a
          lot of extra effort, and rather heavy and cumbersome.
          "" */

          Hi James,

          You say "heavy and cumbersome", I said "a few dollars more". <G>
          ( ever pay for those extended warrenties at Circuit City? ever need them?
          :-} )
          [ Circuit City is an electronics store who "push" customers to buy extra
          protection. Have them in France (yet)? ]

          /* ""
          In case you can't do that, here is a short example:
          { // main of func
          std::ios_base:: fmtflags oldFlg =
          cout.setf(std:: ios_base::fixed , std::ios::float field);
          int OutPre = cout.precision( 40); // save prec, change to 40
          // ------- use it here
          cout.setf( oldFlg, std::ios::float field ); // reset what you need
          cout.precision( OutPre ); // restore orig precision
          }
          Here you pay another price, you need to 'reset' everything you changed.
          This doesn't solve the problem. What happens if there is an
          exception when you are using it? I thought everyone used RAII
          here, and had their own SaveFormat or whatever class, so that
          you'd write:
          SaveFormat saver( std::cout ) ;
          // whatever...
          and when the destructor of saver was called, the original format
          would be restored.
          """ */

          Really hard for a 'newbie' to write a super-duper manipulator class if you
          don't know the basics of the streams.
          Example:
          Hey, OP, do you know what "RAII" is? Exceptions? 'pass by value' vs. 'pass
          by reference'?

          Maybe he/she knows them, but I couldn't tell from the original post.

          I am certainly not arguing with you (who be WAY up the mountain from me).
          Just attempting to give my logic in answering the OP. <G>
          [ I posted part of my early 'tests'.]

          To OP: always listen to 'The Kanze'. If James says something questionable,
          you'll see a very long thread of discussion following! <G>
          --
          Bob R
          POVrookie


          Comment

          • barcaroller

            #6
            Re: Manipulator question...


            "BobR" <removeBadBobR@ worldnet.att.ne twrote in message
            news:nwG5i.4811 2$p47.23534@bgt nsc04-news.ops.worldn et.att.net...
            Hey, OP, do you know what "RAII" is? Exceptions? 'pass by value' vs.
            'pass
            by reference'?
            To OP: always listen to 'The Kanze'. If James says something questionable,
            you'll see a very long thread of discussion following! <G>
            Thank you both for your very useful responses. Yes, I am familiar with the
            C++ concepts mentioned above and in fact I have written my own manipulators
            in the past. I just needed to know if there was a way to use the standard
            manipulators as described in my first posting.


            Comment

            • sebor@roguewave.com

              #7
              Re: Manipulator question...

              On May 23, 3:33 pm, "barcarolle r" <barcarol...@mu sic.netwrote:
              When I use an iostream manipulator in a cout statement, it seems to affect
              all subsequent cout statements.
              >
              cout << x << endl; // dec by default
              cout << hex << x << endl; // hex
              cout << x << endl // still hex
              >
              Is there a way I can have manipulators affect only the "current" cout
              statement?
              Not without writing a bit of code. Here's a simple example
              implementation
              of such a manipulator in the Apache C++ Standard Library:


              Note that simple user-defined manipulators depend on an implementation
              defined type referred to as "smanip" and thus aren't necessarily
              portable.
              With more effort it is possible to write one's own manipulators that
              are
              completely portable, but I didn't go that far in the example.

              Comment

              • James Kanze

                #8
                Re: Manipulator question...

                On May 25, 9:10 pm, "BobR" <removeBadB...@ worldnet.att.ne twrote:

                [...]
                Really hard for a 'newbie' to write a super-duper manipulator class if you
                don't know the basics of the streams.
                Example:
                Hey, OP, do you know what "RAII" is? Exceptions? 'pass by value' vs. 'pass
                by reference'?
                A newbie asking a question here presumably wants to learn. What
                bothers me most is the number of experienced programmers who
                don't know how to right a manipulator. Or perhap rather, who
                don't know when they should write one.
                Maybe he/she knows them, but I couldn't tell from the original post.
                Yes. My goal here was just to throw out ideas. After that, the
                original poster can adopt his own policies, according to his
                level (but hopefully, he will be stimulated to find out about
                RAII). (I know of at least one very competent programmer who
                solves the problem by always setting everything, i.e.:
                std::cout << std::dec << i ;
                systematically. That's also a solution.)
                I am certainly not arguing with you (who be WAY up the mountain from me).
                Just attempting to give my logic in answering the OP. <G>
                I wasn't complaining about your solution; I use it myself often
                enough. I just thought it worth pointing out that there are
                really a lot of solutions (and no one right answer).

                --
                James Kanze (Gabi Software) email: james.kanze@gma il.com
                Conseils en informatique orientée objet/
                Beratung in objektorientier ter Datenverarbeitu ng
                9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                Comment

                • BobR

                  #9
                  Re: Manipulator question...


                  James Kanze <james.kanze@gm ail.comwrote in message ...
                  I just thought it worth pointing out that there are
                  **really a lot of solutions (and no one right answer).**
                  (In C++,) IMHO, that is a big understatement! <G>
                  [ ....considering some/many compilers have 'asm'. [1] ]

                  Thanks James.

                  - -
                  Bob R
                  POVrookie
                  [1] Weird - I came to C++ from Assembler (in 2000), and I've never even
                  tried 'asm' in C++! <G(never found a good reason to.).


                  Comment

                  • sebor@roguewave.com

                    #10
                    Re: Manipulator question...

                    On May 23, 3:33 pm, "barcarolle r" <barcarol...@mu sic.netwrote:
                    When I use an iostream manipulator in a cout statement, it seems to affect
                    all subsequent cout statements.
                    >
                    cout << x << endl; // dec by default
                    cout << hex << x << endl; // hex
                    cout << x << endl // still hex
                    >
                    Is there a way I can have manipulators affect only the "current" cout
                    statement?
                    Not without writing a bit of code. Here's a simple example
                    implementation
                    of such a manipulator in the Apache C++ Standard Library:


                    Note that simple user-defined manipulators depend on an implementation
                    defined type referred to as "smanip" and thus aren't necessarily
                    portable.
                    With more effort it is possible to write one's own manipulators that
                    are
                    completely portable, but I didn't go that far in the example.

                    Comment

                    Working...