Any ideas? binary file reading.

I am trying to read a header binary file and output the contents of the file. I know what the output should look like and am getting a portion of the correct data but the rest is outputting as characters or other garbage.

The output should be in the following format...
Version: 4
Code: 0 - OK
Total Length: 95
Service Type: 2 - High Priority
Grumpy: 1
Sneezy: 0
Bashful: 1
Doc: 0
Dopey: 0
Tipsey: 0
Surley: 1
SnowWhite: 1
Hop Count: 42
Source Address: 222.222.222.222
Dest Address: 4.3.2.1
Data: Some data....

All I am able to get in my table is the total length of 95 and the hop count of 42. Everything else is either garbage or a chacter (@ seems to be popular). Any helpful tips to point me in the right direction are greatly appreciated. Thanks in advance.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 #include <iostream>
#include <fstream>
#include <cctype>
#include <string>
//#pragma pack

using namespace std;

// header struct definition
struct s_header {
	unsigned char verCode;
	unsigned char serviceType;
	unsigned short totLength;
	unsigned char reserved;
	unsigned char flags;
	unsigned short hopCount;
	unsigned long srcAddr;
	unsigned long destAddr;
} fileheader;// you can make a global header variable RIGHT HERE if you want to

// string tables
char * codes[] = {
	"OK",
	"Possible data corruption"
	"Reserved"
};

char * services[] = {
	"Normal",
	"Low Priority",
	"High Priority",
	"Medium Priority",
	"So-so Priority",
	"Needed Yesterday",
	"Nevermind"
	"Reserved"
};

char * flags[] = {
	"Grumpy",
	"Sneezy",
	"Bashful",
	"Doc",
	"Dopey",
	"Tipsy",
	"Surly",
	"Snow White"
};

int main(int argc, char * argv[]) {
	char buffer[1024];
	char ch;
	int size, x;

	ifstream myfile("PACKETS.txt", ios::in | ios::binary);
	if (!myfile) {
		cout << "Cannot open file.\n";
		return 1;
	}
	
	myfile.read((char *)& fileheader, sizeof s_header);
	size = fileheader.totLength - 32; // calculate data size

	cout << "Version: " << fileheader.verCode << endl;
	cout << "Code: " << fileheader.verCode << endl;
	cout << "Total Length: " << fileheader.totLength << endl;
	cout << "Service Type: " << fileheader.serviceType << endl;
	cout << "Hop Count: " << fileheader.hopCount << endl;
	cout << "Source Address: " << fileheader.srcAddr << endl;
	cout << "Dest Address: " << fileheader.destAddr << endl;	
	cout << "Data: ";


	myfile.close();
	cout << endl;
	system("pause");
}
Last edited on
Lines 64,65,67: You're trying to display unsigned chars that contain binary data. The compiler thinks they have ASCII data and is trying to display the fields as such.

Try this instead to display unsigned chars as binary data:
 
cout << "Version: " << (int) fileheader.verCode << endl;


Line 62: Why are you subtracting 32? You should be using the sizeof() operator. Be careful. Your code is not portable. You will get a different size header and different alignment depending on whether you're using a 32 bit or 64 bit compiler.


Last edited on
Anon, I have since added the sizeof for portability.
In regards to the (int) fileheader.vercode the output is now 64 instead of just 4.
Nevermind I used this to shift it; fileheader.verCode = fileheader.verCode >> 4;

As far as the serice type goes I need to convert this "C" code to "C++"
1
2
3
4
5
6
7
8
9
printf("Service Type:\t%i - %s\n", header.serviceType, services[header.serviceType]);

		// display flags using a mask and loop
		x = header.flags;
		for (i = 0; i < 8; i++) {
			printf("  %-7s:\t%d\n", flags[i], x & 1);
			x = x >> 1;
		}


This is what I have, it generates the text but not the actual code:

1
2
3
4
5
6
7
8
9
10
cout << "Service Type: " << setw(3) << fileheader.serviceType << " - ";
	for (int i = 0; i < sizeof(fileheader.serviceType); i++) {
		cout << services[i] << endl;
		//printf("  %-7s:\t%d\n", codes[i], code & 1);
		//code = code >> 1;
	}
	x = fileheader.flags;
	for (int i = 0; i < 8; i++) {
		printf("  %-7s:\t%d\n", flags[i], x & 1);
		x = x >> 1;
Last edited on
Topic archived. No new replies allowed.