Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. ofstream can't write a "double" value into a file correctly

ofstream can't write a "double" value into a file correctly

Scheduled Pinned Locked Moved C / C++ / MFC
iosquestion
14 Posts 4 Posters 2 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Joseph Marzbani
    wrote on last edited by
    #1

    I've a structure like this: struct STRUCT { bool b; int i; double d; }str; // initializing str.b = true; str.i = 18; str.d = 20 and because I know I can't get the real size of a structure using operator sizeof, I write it into a file in this way:

    wofstream of("FileName.dat", ios:out
    of.write(reinterprete_cast <char*> (&str.b), sizeof(bool));
    of.write(reinterprete_cast <char*> (&str.i), sizeof(int));
    of.write(reinterprete_cast <char*> (&str.d), sizeof(double));

    and finally when I read it again into "str" and display it using cout, I got this values: str.b = true; str.i = 18; str.d = 20.001 why 20.001 instead of 20 is written? I took a look into the file using a HEX-Editor and I saw 20.001!!!

    G A L 3 Replies Last reply
    0
    • J Joseph Marzbani

      I've a structure like this: struct STRUCT { bool b; int i; double d; }str; // initializing str.b = true; str.i = 18; str.d = 20 and because I know I can't get the real size of a structure using operator sizeof, I write it into a file in this way:

      wofstream of("FileName.dat", ios:out
      of.write(reinterprete_cast <char*> (&str.b), sizeof(bool));
      of.write(reinterprete_cast <char*> (&str.i), sizeof(int));
      of.write(reinterprete_cast <char*> (&str.d), sizeof(double));

      and finally when I read it again into "str" and display it using cout, I got this values: str.b = true; str.i = 18; str.d = 20.001 why 20.001 instead of 20 is written? I took a look into the file using a HEX-Editor and I saw 20.001!!!

      G Offline
      G Offline
      Garth J Lancaster
      wrote on last edited by
      #2

      its not a problem with ofstream - its a problem with your understanding of how floating point numbers are handled by computers - I suggest you start reading here for example : http://www.johndcook.com/blog/2009/04/06/anatomy-of-a-floating-point-number/[^] 'g'

      J 1 Reply Last reply
      0
      • G Garth J Lancaster

        its not a problem with ofstream - its a problem with your understanding of how floating point numbers are handled by computers - I suggest you start reading here for example : http://www.johndcook.com/blog/2009/04/06/anatomy-of-a-floating-point-number/[^] 'g'

        J Offline
        J Offline
        Joseph Marzbani
        wrote on last edited by
        #3

        Thank you! but one expects to get whatever he's saved on a file as the original value. I'll read that article for sure. but for now could you explain what should I do to save and retrive a "double" value. a short exam will be appreciated.

        G 1 Reply Last reply
        0
        • J Joseph Marzbani

          Thank you! but one expects to get whatever he's saved on a file as the original value. I'll read that article for sure. but for now could you explain what should I do to save and retrive a "double" value. a short exam will be appreciated.

          G Offline
          G Offline
          Garth J Lancaster
          wrote on last edited by
          #4

          that article explains why you are seeing that value - what you are seeing is 20 +/- epsilon, written out with the precision you specified (or rather in this case, didnt specify) you need to look at using <iomanip> and the precision specifier at least so google iomanip and precision 'g'

          J 1 Reply Last reply
          0
          • J Joseph Marzbani

            I've a structure like this: struct STRUCT { bool b; int i; double d; }str; // initializing str.b = true; str.i = 18; str.d = 20 and because I know I can't get the real size of a structure using operator sizeof, I write it into a file in this way:

            wofstream of("FileName.dat", ios:out
            of.write(reinterprete_cast <char*> (&str.b), sizeof(bool));
            of.write(reinterprete_cast <char*> (&str.i), sizeof(int));
            of.write(reinterprete_cast <char*> (&str.d), sizeof(double));

            and finally when I read it again into "str" and display it using cout, I got this values: str.b = true; str.i = 18; str.d = 20.001 why 20.001 instead of 20 is written? I took a look into the file using a HEX-Editor and I saw 20.001!!!

            A Offline
            A Offline
            Aescleal
            wrote on last edited by
            #5

            Firstly - of course you can get the size of a structure using sizeof - that's what it's there for. It's only when you make some crass assumptions about what sizeof does that you get into trouble. Secondly are you sure the code you've presented to us, HTML foobars aside, is the code you've been using? The reason I ask is that a standard conforming compiler won't accept the line:

            of.write(reinterpret_cast <char*> (&str.b), sizeof(bool));

            as the first parameter to std::basic_stream<char_type>::write is char_type * or wchar_t * for a wofstream. So the first thing I'd do is grab a standard comforming C++ compiler and give your code another go. Cheers, Ash

            J 1 Reply Last reply
            0
            • G Garth J Lancaster

              that article explains why you are seeing that value - what you are seeing is 20 +/- epsilon, written out with the precision you specified (or rather in this case, didnt specify) you need to look at using <iomanip> and the precision specifier at least so google iomanip and precision 'g'

              J Offline
              J Offline
              Joseph Marzbani
              wrote on last edited by
              #6

              thank you! It was really helpful

              1 Reply Last reply
              0
              • A Aescleal

                Firstly - of course you can get the size of a structure using sizeof - that's what it's there for. It's only when you make some crass assumptions about what sizeof does that you get into trouble. Secondly are you sure the code you've presented to us, HTML foobars aside, is the code you've been using? The reason I ask is that a standard conforming compiler won't accept the line:

                of.write(reinterpret_cast <char*> (&str.b), sizeof(bool));

                as the first parameter to std::basic_stream<char_type>::write is char_type * or wchar_t * for a wofstream. So the first thing I'd do is grab a standard comforming C++ compiler and give your code another go. Cheers, Ash

                J Offline
                J Offline
                Joseph Marzbani
                wrote on last edited by
                #7

                that code was what I got in real! by the way, did you mean I can rely on "sizeof" to write/read a whole structure into a file aborting that "padding" stuff? like when I don't know how it works under the hood

                A 1 Reply Last reply
                0
                • J Joseph Marzbani

                  I've a structure like this: struct STRUCT { bool b; int i; double d; }str; // initializing str.b = true; str.i = 18; str.d = 20 and because I know I can't get the real size of a structure using operator sizeof, I write it into a file in this way:

                  wofstream of("FileName.dat", ios:out
                  of.write(reinterprete_cast <char*> (&str.b), sizeof(bool));
                  of.write(reinterprete_cast <char*> (&str.i), sizeof(int));
                  of.write(reinterprete_cast <char*> (&str.d), sizeof(double));

                  and finally when I read it again into "str" and display it using cout, I got this values: str.b = true; str.i = 18; str.d = 20.001 why 20.001 instead of 20 is written? I took a look into the file using a HEX-Editor and I saw 20.001!!!

                  L Offline
                  L Offline
                  Lost User
                  wrote on last edited by
                  #8

                  Joseph Marzbany wrote:

                  I can't get the real size of a structure using operator sizeof

                  If that were the case then lots of programs would not work. If you write the structure using sizeof and read it back in the same way then you will restore the exact same structure every time. Only if you use different padding options in your code would you have a problem.

                  It's time for a new signature.

                  J 1 Reply Last reply
                  0
                  • J Joseph Marzbani

                    that code was what I got in real! by the way, did you mean I can rely on "sizeof" to write/read a whole structure into a file aborting that "padding" stuff? like when I don't know how it works under the hood

                    A Offline
                    A Offline
                    Aescleal
                    wrote on last edited by
                    #9

                    Well if that code was what you got "in real" then perhaps you're using a cranky old C++ compiler. If you read from or write to a wofstream then the first parameter is a wchar_t pointer - this is standard and completely non-negotiable. I've checked that one line on 9 compilers (one being Comeau which is the best you're ever going to get for C++98/03 standard compliance - I know, my life is so meaningless) and none of them compiled the code. They all gave me a warning that the code was incorrect. And I meant exactly what I said - when you ask a particular compiler what the size of a structure is it'll always give the same answer with the same build settings.

                    J 1 Reply Last reply
                    0
                    • A Aescleal

                      Well if that code was what you got "in real" then perhaps you're using a cranky old C++ compiler. If you read from or write to a wofstream then the first parameter is a wchar_t pointer - this is standard and completely non-negotiable. I've checked that one line on 9 compilers (one being Comeau which is the best you're ever going to get for C++98/03 standard compliance - I know, my life is so meaningless) and none of them compiled the code. They all gave me a warning that the code was incorrect. And I meant exactly what I said - when you ask a particular compiler what the size of a structure is it'll always give the same answer with the same build settings.

                      J Offline
                      J Offline
                      Joseph Marzbani
                      wrote on last edited by
                      #10

                      congratulations! You're life's so meaningful :) cause I'd behaved so stupid!!! I was wrong and my compiler had emitted a warning too. and one more thing! thnx 4 introducing that modern compilet.

                      1 Reply Last reply
                      0
                      • L Lost User

                        Joseph Marzbany wrote:

                        I can't get the real size of a structure using operator sizeof

                        If that were the case then lots of programs would not work. If you write the structure using sizeof and read it back in the same way then you will restore the exact same structure every time. Only if you use different padding options in your code would you have a problem.

                        It's time for a new signature.

                        J Offline
                        J Offline
                        Joseph Marzbani
                        wrote on last edited by
                        #11

                        you're right (and I'm left :) but I meant "the sum of all memberss' size" when I said "the size of a structure". by the way do u know how I can make the compiler ignore that PADDING stuff? I mean a STANDARD way not an implementation-specific one. thnx

                        modified on Wednesday, August 18, 2010 11:24 PM

                        L 1 Reply Last reply
                        0
                        • J Joseph Marzbani

                          you're right (and I'm left :) but I meant "the sum of all memberss' size" when I said "the size of a structure". by the way do u know how I can make the compiler ignore that PADDING stuff? I mean a STANDARD way not an implementation-specific one. thnx

                          modified on Wednesday, August 18, 2010 11:24 PM

                          L Offline
                          L Offline
                          Lost User
                          wrote on last edited by
                          #12

                          Joseph Marzbany wrote:

                          but I meant "the sum of all memberss' size" when I said "the size of a structure".

                          Sure, but why worry about a few extra bytes, which will not have any significant effect on either your program or your files? If you want to pack your structure tightly then use the #pragma pack()[^] compiler directive.

                          It's time for a new signature.

                          J 1 Reply Last reply
                          0
                          • L Lost User

                            Joseph Marzbany wrote:

                            but I meant "the sum of all memberss' size" when I said "the size of a structure".

                            Sure, but why worry about a few extra bytes, which will not have any significant effect on either your program or your files? If you want to pack your structure tightly then use the #pragma pack()[^] compiler directive.

                            It's time for a new signature.

                            J Offline
                            J Offline
                            Joseph Marzbani
                            wrote on last edited by
                            #13

                            thank you for your attention! 1. is that a STANDARD method or Implementation-Specific? (Yes I know I've already asked it. Just for sure) 2. What's that padding stfuff useful for? Why do compilers take such a strategy?

                            L 1 Reply Last reply
                            0
                            • J Joseph Marzbani

                              thank you for your attention! 1. is that a STANDARD method or Implementation-Specific? (Yes I know I've already asked it. Just for sure) 2. What's that padding stfuff useful for? Why do compilers take such a strategy?

                              L Offline
                              L Offline
                              Lost User
                              wrote on last edited by
                              #14

                              1. I think the compiler writers are allowed to decide what their default option will be. 2. Padding of short items allows the compiler to take advantage of processor hardware. In some cases the system is more efficient if words, double words etc are aligned on even boundaries.

                              It's time for a new signature.

                              1 Reply Last reply
                              0
                              Reply
                              • Reply as topic
                              Log in to reply
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes


                              • Login

                              • Don't have an account? Register

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • World
                              • Users
                              • Groups