Writing and reading unsigned chars to binary file
Asked Answered
S

4

5

I am writing a simple program that writes to a binary file, closes it and then reads the data that was just written. I am trying to write an array of unsigned characters. I am experiencing some issues while reading the data. I am not exactly sure if I am writing the data improperly or reading it wrong. When I read the data I get my output as: 5 bytes for the number of bytes read, but the output I got was not the same as the values I had wrote to the file.

FILE *binFile = fopen("sample","wb");

unsigned char data[5]={5,10,15,20,25};
fwrite(data,sizeof(unsigned char),sizeof(data),binFile);
fclose(binFile);

unsigned char data2[5];
binFile = fopen("sample","rb");
int s = fread(data2,1,sizeof(data),binFile);
fclose(binFile);
cout<<s<<" bytes\n";
for(int i=0; i<5;i++)
        cout<<data2[i]<<" ";
cout<<"\n";
Stool answered 26/7, 2013 at 8:14 Comment(2)
How many bytes you are expecting to be written?Tedric
try this array values data[5]={'a', 'b', 'c', 'd', 'e'}; with your code without typecase I think then your doubt will be clear beater. You are writing acsii values you to are printing ascii value con get coveted into char-symbolShastashastra
B
7

What you are receiving as output seeing are ASCII characters of elements of array

Typecast unsigned char to int

This will give expected output.

for(int i=0; i<5;i++)
        cout<<(int)data2[i]<<" ";
Biron answered 26/7, 2013 at 8:21 Comment(1)
you are receiving as output seeing are ASCII characters yes he is also writing ascii values, writing 5 instead of char '5' . good pick POW!Shastashastra
C
3

What you see is valid and normal behavior when you print non-printable characters like ASCII - 5,10,15,20,25. It looks different when they are printed as character. So either you can try with cast to int or you can try with printable character (char) like A, B, C, D, E

Your code could behave as expected with,

1) Assigning printable characters,

    unsigned char data[5]={'A','B','C','D','E'};

or

2) Casting the output to int,

    for(int i=0; i<5;i++)
       cout<< (int) data2[i]<<" ";
Credendum answered 26/7, 2013 at 8:24 Comment(0)
I
2

I guess you got the output with some characters like 'sign of club' and then on next line you see 3 other characters, right?

If you check ASCII table, then ASCII 5, 10, 15, 20 and 25 are the same what are displayed on screen. ASCII 10 is '\n' char hence your 2nd character from the array prints output on 2nd line :)

Imaginal answered 26/7, 2013 at 8:46 Comment(0)
T
1

Sizeof data is 5 and sizeof (unsigned char) is always 1 Therefore you wrote 5 bytes. Check the return of fwrite (number of items read or written). Also you read 5 bytes therefore fread will return 5.

According to C99 Section 6.5.3.4 Paragraph 3 and C11 Section 6.5.3.4 Paragraph 4

When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1. When applied to an operand that has array type, the result is the total number of bytes in the array. 88) When applied to an operand that has structure or union type, the result is the total number of bytes in such an object, including internal and trailing padding.

On the other hand whatever you are printing is not getting displayed because the number ranges which you are printing are non-printable ASCII range. Assign something higher than 32 or start something from 65 to see results. Or simply initialize using 'A', 'b', etc.

OR with the existing code, when printing typecast to int cout<<int (data2[i])<<" ";

Tedric answered 26/7, 2013 at 8:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.