Home > Net >  C question: I'm having problems writing array of doubles (single precision 32 bit) to a disc
C question: I'm having problems writing array of doubles (single precision 32 bit) to a disc

Time:03-20

I have an application I'm trying to write in which will take a table of numbers (generated by user) and write the table to a file on disc. This file will then later be transferred to an Arduino AVR device over USB to its EEPROM. The format I wish to save this information in on disc is 4-byte Little Endian as just raw Hex data. My table array called "tbl1Array[]" in my code below has been cast as a double. Below is a snippet of the bunk code I have in place now, in-line following some array preparation code. The file open/close works fine, and in fact, data DOES get transferred to the file, but the format is not what I want.

        ofstream fileToOutput("318file.bin");                  
            for (int i=0; i<41; i  )    
            {
                fileToOutput << tbl1Array[i];            
            }
            fileToOutput.close();

THE PROBLEM is that what is written to the file is a hex ASCII representation of the decimal value. Not what I want! I don't know what I need to do to get my array as a nice neat concatenated list of 4-byte Little Endian words for my doubles that I can later read from within the Arduino code. I have a working method for transferring the file to the Arduino using AVRDUDE (tested and confirmed), so my only real hang-up is getting these doubles in my applications' array to 4-byte IEEE754 on disc. Any guidance would be greatly appreciated. Regards - Mark

CodePudding user response:

  1. In a text stream, the new-line character is translated. Some operating systems translated to \r\n. A binary stream leaves it as it is.

  2. Regardless of how you opened the stream – binary or text:

    a. When you use the insertion/extraction operator the data is written as text. Assuming 0x01 is a one byte integer, ASCII 1 will be written (that is 0x31).

    b. If you use the ostream::write method, you write the actual bytes; no translations happens. Assuming 0x01 is a one byte integer, 0x01 will be written.

  3. If you want to write the actual bytes, open the stream in binary mode and use ostream::write:

    ofstream os{ "out.bin", ios::binary };
    if (!os)
      return -1;
    double d = 1.234567;
    os.write((const char*)&d, sizeof d);
    
  4. If you want to write the actual bytes as a string, open the stream in text mode and use the insertion operator:

    ofstream os{ "out.txt" };
    if (!os)
      return -1;
    double d = 1.234567;
    static_assert(sizeof(double) == sizeof(long long));
    os << hex << *reinterpret_cast<long long*>(&d);
    
  5. If you want to write a double as string, using the maximum precision use:

    os << setprecision(numeric_limits<double>::max_digits10) << d;
    
  6. Don't use translated & untranslated methods on the same stream.

I do not know if all above examples will work on an Arduino compiler.

  • Related