1

I need to write some C code that writes doubles out to file.

For some values, fwrite writes the correct 8-byte binary to file. For other values, it seems to prepend an extra 9th byte. For example, this code writes 9 bytes comprising x0d, followed by the correct 8 bytes:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <float.h>

#define PI 3.14159265358979323846

int main()
{
    // Generate a number
    double x = -3.0 * cos(PI * 5.0 / 8.0);
    printf("%.*e\n", DECIMAL_DIG, x);

    // Uncomment this to get an 8-byte file instead of 9
    // x = (float) x;

    // Write number to file
    FILE* fw = fopen("out.bin", "w");
    if (fw != NULL)
    {
        size_t Nw = fwrite(&x, sizeof(double), 1, fw);
        printf("Wrote %i values to file.\n", Nw);

        if (fclose(fw) != 0)
            return (EXIT_FAILURE);
    }
    else
        return (EXIT_FAILURE);

    return (EXIT_SUCCESS);
}

However, if I change the value, for example to double x = -3.0 * cos(PI * 3.0 / 8.0);, or even if I just cast the number to float and back again (see "Uncomment this..." in the above code), then the correct 8 bytes are written.

I am compiling with MinGW GCC-6.3.0-1. What am I doing wrong?

Harry
  • 884
  • 1
  • 8
  • 19
  • 1
    Open the file in binary mode. – Weather Vane Mar 27 '19 at 18:05
  • Possible duplicate of [Difference between files written in binary and text mode](https://stackoverflow.com/questions/229924/difference-between-files-written-in-binary-and-text-mode) – AShelly Mar 27 '19 at 18:09
  • @Harry the [man page](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-wfopen?view=vs-2017) is preferable to googling. – Weather Vane Mar 27 '19 at 18:16
  • @WeatherVane To be honest, even on that man page, the access mode modifiers are pretty well hidden! But you're right, at least they're there. – Harry Mar 27 '19 at 18:21
  • @Harry there are four paragraphs about the mode, including "If **t** or **b** is not given in *mode*, the default translation mode is defined by the global variable `_fmode`." – Weather Vane Mar 27 '19 at 18:25

1 Answers1

4

You opened the file in text mode, and are writing binary data to it. Windows changes LF 0x0a to CRLF 0x0d 0x0a. You need to use "wb" as the 2nd argument when opening the file.

AShelly
  • 34,686
  • 15
  • 91
  • 152
  • Thank you. The first result in google only listed "r", "w", "a", "r+", "w+" and "a+". Ahhh, that explains why it was only happening for some specific values! I'm surprised that "text mode" is the default. – Harry Mar 27 '19 at 18:12