Search code examples
chexhex-editors

fprintf writting 0D 0D 0A instead of 0D 0A in a txt file


I'm trying to write a sample text using c, but my code is doing it wrong.
the code is below

#include <stdio.h>

int main(){
FILE *ptr;
char c[8]={65,66,67,13,10,67,68,69};
int count;
ptr = fopen("write.txt","w");
for(cont = 0 ; cont < 8; count++){
     fprintf(ptr, "%c", c[count]);
}
return 0;
}

The text should be
ABC
CDE

But when I open it in a hex editor, this is what it display:

41 42 43 0D 0D 0A 43 44 45 

Edit: I put wb instead of w and it works


Solution

  • Opening a file in text mode opens you up to having your data translated in certain ways, to comply with the requirements of the underlying environment.

    For example, in Windows, opening a file in text mode may mean that the C concept of a newline character \n maps to and from the CRLF character sequence in the file.

    Hence, when you write the 13 (CR), it goes out as is. When you write the 10 (LF), that's the newline character \n and is translated to Windows line endings, CRLF. That's why you're seeing 0D 0D 0A in the file.

    If you want to avoid this translation, just open the file in binary mode(a):

    ptr = fopen("write.txt", "wb");
    

    As an aside, it's also a good idea to:

    • check functions that can fail to see if they do fail (for example, fopen returning NULL or fprintf returning anything other than one (in this case));
    • close files explicitly when you're done with them;
    • let C automatically size your arrays where possible (char c[] = {...}); and
    • use sizeof(c) rather than the "magic" number 8.

    (a) The relevant part of ISO C11 is 7.21.2 Streams /2:

    A text stream is an ordered sequence of characters composed into lines, each line consisting of zero or more characters plus a terminating new-line character. Whether the last line requires a terminating new-line character is implementation-defined. Characters may have to be added, altered, or deleted on input and output to conform to differing conventions for representing text in the host environment. Thus, there need not be a one-to-one correspondence between the characters in a stream and those in the external representation.

    But just keep in mind that even binary data may not go unmodified, as per /3 in that same section:

    A binary stream is an ordered sequence of characters that can transparently record internal data. Data read in from a binary stream shall compare equal to the data that were earlier written out to that stream, under the same implementation. Such a stream may, however, have an implementation-defined number of null characters appended to the end of the stream.

    The only time I personally have ever seen that clause come into play is on the System z mainframes with fixed length record sizes that had to be padded out.