-5

folks, this is an example I took from the Internet, I modified it a bit, the 'wb' to 'w', and 'bin' to 'txt' for the sake of understanding it.


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

int main()
{
   FILE * fp;
   int x = 0, i = 0;

   fp = fopen ("TestFile.txt", "w");

   for(i=0; i<10 ;i++) {
       x = i;
       fwrite(&x,sizeof(int),1,fp);
   };

   fclose(fp);
   return(0);
}

What is really happening here? 1 The 'w' mean that I want to write in a textfile. 2 What is stored inside is in binary format. Question 1&2: The extension doesn't mean anything here, is the 'w' that defines that it is a textfile, even with inside data in binary?

3 The fact that I'm trying to store a 4 bytes inside a file that accepts 1 byte transform it in binary?

I know that I can create plain text this way.

char y = i + '0';
fwrite(&y,sizeof(char),1,fp);

4 Anyone actually stores numbers in plain text? How, what's the best way to do that? Thanks in advance.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • 2
    _I modified it a bit, the 'wb' to 'w', and 'bin' to 'txt'_ Best not to do that... – Paul Sanders Mar 20 '23 at 23:22
  • 3
    *I modified it a bit, the 'wb' to 'w', and 'bin' to 'txt' for the sake of understanding it.* - just now it's wrong. You are still writing binary data, in text mode, which can bring you surprises. https://stackoverflow.com/questions/229924/difference-between-files-written-in-binary-and-text-mode – tevemadar Mar 20 '23 at 23:22
  • 1
    For human readable storage format, use `fprintf(fp, "%d ", y)`. Or use `std::ofstream`. – Thomas Matthews Mar 20 '23 at 23:31
  • 1
    If you are using Windows, to see one of the common side effects of removing the b, modify the code to write the number 10. The file writer will see the 10, interpret it as a newline, and write a 13, carriage return, along with the 10 to the file in order to present a proper text file line ending to the reader. – user4581301 Mar 20 '23 at 23:34
  • @user4581301 you're absolutely right, it does make the difference, on windows 10 and forth print something else, on "onlinegdb.com" the number 13 is printed as 10. Thanks. – Wesley Pimentel Mar 21 '23 at 07:22

2 Answers2

4

Question 1&2: The extension doesn't mean anything here,

Correct.

is the 'w' that defines that it is a textfile, even with inside data in binary?

The w as opposed to wb means that it is opened as a text file, yes. The implications are system-dependent, but lower-level than you seem to have expected. On Linux and MacOS, there is no practical difference between the two. On Windows, the only difference I'm aware of is that the system automatically translates between newlines internally and carriage return / newline pairs externally. Historically, and maybe still today, there have been systems where the differences were more significant.

In your case, you get raw binary data in the file because you write it with an I/O function (fwrite) that serves that purpose. If you want formatted text in your text file then use fprintf() to write it, or format it into text format in a string and write that.

3 The fact that I'm trying to store a 4 bytes inside a file that accepts 1 byte transform it in binary?

I'm not sure exactly what you mean, but you're getting binary data in the file because that's what fwrite() does.

4 Anyone actually stores numbers in plain text?

Yes, it's fairly common. There are multiple ways to do it; see above for two.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • 2
    On 4) storing data as text might not be the most efficient way, but is safe and portable. When the tools you use to read the home-made file format break, there it is in human readable form, and is accesssible. – Weather Vane Mar 20 '23 at 23:59
  • Thanks, I thought that only open(), write() and read() were lower level functions to work with binaries... – Wesley Pimentel Mar 21 '23 at 00:51
  • 1
    @WesleyPimentel, `open()`, `write()`, and `read()` are in an entirely different category. These are not part of the C language specification at all, but are specified instead by POSIX. Only some C language implementations have them. – John Bollinger Mar 21 '23 at 00:54
4

The primary thing that distinguishes whether you're writing "text" or "binary" format is the function that you call to do it. Everything else is secondary.

If you're calling

fwrite(&x, sizeof(int), 1, fp);

then you're writing a binary representation: generally 2 or 4 bytes, in a compact, binary, non human readable format.

On the other hand, if you're calling

fprintf(fp, "%d\n", x);

then you're writing a nice, human-readable "text" format, with as many digit characters as it takes to represent the number x.

Generally, if you're calling fwrite, then you should have opened the file mode "wb" (although this is not required, as it's quite possible to use fwrite to write text, too, such as with your fwrite(&y, sizeof(char), 1, fp) example).

Generally, if you're calling fprintf, then you should have opened the file mode "w" (although it's not an error to do otherwise).

And the filenames and extensions you use are totally up to you: C doesn't look at those, C doesn't care.

It seems maybe you thought that one or the other of

  • using "w" instead of "wb"
  • naming the file .txt instead of .bin

might somehow change the functionality of the fwrite function. But nothing could be farther from the truth. Remember, C is a low-level language: it generally does exactly what you tell it, there's no "DWIM" functionality.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103