Problems with reading binary data files

D

Dimitri Papoutsis

Hi there, ...

i want to read in a binary data file and to cast each pair of 2 bytes to a
signed short value. i try to different ways, but none results in what i
suppose it should result.

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

int main(){
        char file_name[13];
        FILE* fptr;
        signed short c;
        
        printf("Enter a filename: ");
        gets(file_name);
        
        // Variation A: Using the standart fopen, fgetc, fclose functions
        if ((fptr = fopen(file_name,"rb")) == 0){
                printf("Sorry. Can't open file \"%s\"\n", file_name);
                exit (EXIT_FAILURE);
        }
        for(int i=0;i<11;i++){
                c = fgetc(fptr);
                cout << c << "\t";
        }
        cout << "\n";
        fclose(fptr);


        // Variation B: Using the fstream class
        char buffer[24];
        ifstream datei(file_name, ios::in | ios::binary);       
        if(!datei){
                printf("Sorry. Can't open file \"%s\"\n", file_name);
                exit (EXIT_FAILURE);
        }
        datei.read(buffer, 24);
        for (int i=0;i<24;i++){
                cout << (signed short)buffer  << "\t";
        }
        cout << "\n";

        return EXIT_SUCCESS;
}

You can test the program with the following data file:
        http://www.uni-koblenz.de/~bastard/dat.1

The result that i suppose my program to print out can be generated with the
following perl-script:
        http://www.uni-koblenz.de/~bastard/binaryDataRead

=> ./binaryDataRead dat.1
=> Result :
0       -489    -458    31      474     -260    -214    -88     -241    -112   
212     393     390

whereas the "0" is just an index of the printed record.

My Program results in:
=> Variation A:
23      254     54      254     31      0       218     1       252     254    
42      255

=> Variation B:
23      -2      54      -2      31      0       -38     1       -4      -2     
42      -1      -88     -1      15      -1 -112     -1      -44     0      
-119    1       -122    1

About Variation A:
i completely misunderstand the causal dependencies between the code and the
result.

About Variation B:
i see that i always cast and print out just 1 Byte. How can i cast and print
out 2 Bytes ? Are my approaches completly wrong ?

i hope anybody can help...

bye
Dimi
 
S

Scott McPhillips [MVP]

Dimitri said:
Hi there, ...

i want to read in a binary data file and to cast each pair of 2 bytes to a
signed short value. i try to different ways, but none results in what i
suppose it should result.
datei.read(buffer, 24);
for (int i=0;i<24;i++){
cout << (signed short)buffer << "\t";
}


buffer reads a char prior to the cast. To read 2 bytes you can
dereference a pointer to a 2 byte type.

signed short* p = (signed short*) &buffer;
signed short result = *p;

You will also need to modify your loop so i increments 0, 2, 4, ...
 
T

Thomas Matthews

Scott said:
Dimitri said:
Hi there, ...

i want to read in a binary data file and to cast each pair of 2 bytes
to a
signed short value. i try to different ways, but none results in what i
suppose it should result.
datei.read(buffer, 24);
for (int i=0;i<24;i++){
cout << (signed short)buffer << "\t";
}



buffer reads a char prior to the cast. To read 2 bytes you can
dereference a pointer to a 2 byte type.

signed short* p = (signed short*) &buffer;
signed short result = *p;

You will also need to modify your loop so i increments 0, 2, 4, ...


A better method for reading multibyte binary integers is to
read each byte individually and build the value. This will
allow the proper reading of the data file regardless of the
Endianism of the platform.
 
R

red floyd

Dimitri said:
Hi there, ...

i want to read in a binary data file and to cast each pair of 2 bytes to a
signed short value. i try to different ways, but none results in what i
suppose it should result.

#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
non standard header. Use said:
#include <fstream.h>
int main(){
[redacted]
 
O

Old Wolf

Scott said:
Dimitri said:
Hi there, ...

i want to read in a binary data file and to cast each pair of 2 bytes to a
signed short value. i try to different ways, but none results in what i
suppose it should result.
datei.read(buffer, 24);
for (int i=0;i<24;i++){
cout << (signed short)buffer << "\t";
}


buffer reads a char prior to the cast. To read 2 bytes you can
dereference a pointer to a 2 byte type.

signed short* p = (signed short*) &buffer;


Undefined behaviour, if buffer + i isn't correctly aligned
for a short. Also, 'short' is signed, you don't have to write
out the word signed.

Better would be:

short result;
memcpy(&result, buffer, sizeof result);

although this may not work on esoteric systems.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top