Reputation: 343
I have this strange problem:
I write 16 chars to a binary file and then I write 3 integers but when I open my file with some binary file viewer, I see an extra byte is added (which equals 0x0D).
Here's my code:
for(i = 0; i < 16; i++)
{
if(i < strlen(inputStr))
{
myCharBuf[0] = inputStr[i];
}
else
{
myCharBuf[0] = 0;
}
fwrite(myCharBuf, sizeof(char), 1, myFile);
}
myIntBuf[0] = inputNumber1;
fwrite(myIntBuf, sizeof(int), 1 ,myFile);
myIntBuf[0] = inputNumber2;
fwrite(myIntBuf, sizeof(int), 1 ,myFile);
myIntBuf[0] = inputNumber3;
fwrite(myIntBuf, sizeof(int), 1 ,myFile);
I get the following byte-values:
61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0D 0A 00 00 00 05 00 00 00 08 00 00 00
When I expect:
61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0A 00 00 00 05 00 00 00 08 00 00 00
Does anyone have an idea why it might happen?
Upvotes: 18
Views: 10489
Reputation: 44736
0A is the line feed character and 0D is the carriage return. These are usually associated with text mode.
Have you opened the file in binary mode? (e.g. fopen("foo.txt", "wb"
))
Upvotes: 22
Reputation: 300769
When you open the file, open for writing as binary "wb"
:
fopen(filename, "wb");
When you open in text mode, translation of Line Feeds (0A
) and Carriage Returns (0D
) occurs.
Upvotes: 14
Reputation: 508
This code
#include <stdio.h>
#define SECTORSIZE 512 // bytes per sector
int main(int argc, char *argv[])
{
FILE *fp; // filepointer
size_t rdcnt; // num. read bytes
unsigned char buffer[SECTORSIZE];
if(argc < 2)
{
fprintf(stderr, "usage:\n\t%s device\n", argv[0]);
return 1;
}
fp = fopen(argv[1], "rb");
if(fp == NULL)
{
fprintf(stderr, "unable to open %s\n",argv[1]);
return 1;
}
rdcnt = fread(buffer, 1, SECTORSIZE, fp);
if(rdcnt != SECTORSIZE)
{
fprintf(stderr, "reading %s failed\n", argv[1]);
fclose(fp);
return 1;
}
fwrite(buffer, 1, SECTORSIZE, stdout);
fclose(fp);
return 0;
}
kindly taken from here https://redeaglesblog.wordpress.com/2011/04/05/sektoren-eines-datentragers-lesen/
reads the boot sector from any given disk
Pasted as it is in your preferred C (ANSI) IDE or editor, it compiles and works either in windows (mingw passing \.\PhysicalDriveX) and linux (gcc passing /dev/sdX)
But it works like a charm ONLY in Linux while it anyway inserts/adds an x0D preceding any x0A despiting the fp = fopen(argv[1], "rb");
I've compiled it from code::blocks with mingw as readsect.exe
and run it reading the boot sector of my hard drive
c:\readsect.exe \\.\PhysicalDrive0 > read.bin
The file read.bin results with a lenght of 515 bytes instead than 512.
With an HEX editor able to open physical drives, I've compared my boot sector content with the read.bin one.
Well, every x0A in the physical boot sector (x0A is found 3 times), in the read.bin file is dumped as x0D + X0A. So I have three x0D, three bytes more.
Googleing, it looks like a widely reported problem.
Do any of you have found a fix? Maybe stdio.h needs a fix for the windows environment?
Thank you
Upvotes: 0
Reputation:
MS-DOS (and so today with Windows), when writing a file in text mode, adds an 0x0D before every 0x0A. In other words, it processes arbitrary data streams as they go to and from store and messes with their data - utterly, utterly insane.
Open the file in binary mode for non-insane handling.
Upvotes: 1
Reputation: 106
I believe that your inputStr variable contains a newline character and it is written to the binary file as carriage return and linefeed - binary '0D' followed by '0A'.
For eg, the following program writes 16 characters and 3 numbers as follows.
FILE *fp;
fp = fopen("sample.bin", "wb+");
if(fp == NULL)
{
printf("Cannot create a file\n");
return;
}
int i;
char c[1] = {'A'};
for(i = 0; i < 16; i++)
{
fwrite(c, sizeof(char), 1, fp);
c[0]++;
}
int ip[1] = {1};
fwrite(ip, sizeof(int), 1, fp);
fwrite(ip, sizeof(int), 1, fp);
fwrite(ip, sizeof(int), 1, fp);
fclose(fp);
If the 'sample.bin' file is viewed using a dump program such as 'od', it gives the content as follows.
od -t x1 -c sample.bin
0000000 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50
A B C D E F G H I J K L M N O P
0000020 01 00 00 00 01 00 00 00 01 00 00 00
001 \0 \0 \0 001 \0 \0 \0 001 \0 \0 \0
0000034
Upvotes: 1
Reputation: 108986
fopen
the file in binary mode with "wb".
fopen(filename, "wb");
otherwise, the code in the library will do automatic line end translation (on windows you are on Windows, are you not? that means translate '\n'
to '\r' '\n'
).
Upvotes: 9