Updating one element of a struct and writing to a binary file

I've been trying to figure out a simple script to open a data file from an ice hockey management game and made a change to one element of a struct for each record.

I have a struct named STAFF and I want to add 1000 to value of the StaffContractExpiresClub.year element of each record (the 'year' sub-element is part of the SI_DATE struct). I've been trying to use the stream to do this but just cannot to get it to work. Could anybody kindly give me a helping hand (I'm a novice to C/C++)?

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <iostream>
#include <fstream>
#pragma pack(1)

using namespace std;

enum { 
	LONG_TEXT_LENGTH = 101,
	STANDARD_TEXT_LENGTH = 51,
	SHORT_TEXT_LENGTH = 26,
	REAL_SHORT_TEXT_LENGTH = 6,
	THREE_LETTER_TEXT_LENGTH = 4,
	SIX_LETTER_TEXT_LENGTH = 7
};

typedef bool	CBOOL;
typedef char	CHAR;
typedef unsigned char	UCHAR;
typedef short	SHORT;
typedef unsigned short	USHORT;
typedef double	DOUBLE;
typedef long	LONG;
typedef unsigned long	ULONG;
typedef LONG NATIONS_PTR;
typedef LONG CITIES_PTR;
typedef LONG CLUBS_PTR;
typedef LONG STAFF_PTR;
typedef LONG NON_PLAYERS_PTR;
typedef LONG PLAYERS_PTR;
typedef LONG STAFF_PREFERENCES_PTR;
typedef LONG CHAR_PTR;

struct SI_DATE
{
	SHORT day;
	SHORT year;
	CBOOL leap_year;
};

struct STAFF
{
	LONG	 StaffID;
	LONG	 StaffEstimatedWage;
	LONG	 StaffEstimatedValue;
	NATIONS_PTR	 StaffNation;
	NATIONS_PTR	 StaffSecondNation;
	PLAYERS_PTR	 StaffPlayerData;
	STAFF_PREFERENCES_PTR	StaffPreferences;
	NON_PLAYERS_PTR	 StaffNonPlayerData;
	CLUBS_PTR	 StaffNationContracted;
	CLUBS_PTR	 StaffClubContracted;
	CLUBS_PTR	 StaffClubPlaying;
	LONG	 StaffPlayerRightsIndex;
	CITIES_PTR	 StaffBirthTown;
	CHAR_PTR	 StaffFirstName;
	CHAR_PTR	 StaffSecondName;
	SI_DATE	 StaffDateOfBirth;
	SI_DATE	 StaffDateJoinedNation;
	SI_DATE	 StaffContractExpiresNation;
	SI_DATE	 StaffDateJoinedClub;
	SI_DATE	 StaffContractExpiresClub;
	SI_DATE  StaffFirstProContract;
	SHORT	 StaffYearOfBirth;
	UCHAR	 StaffInternationalApps;
	UCHAR	 StaffInternationalGoals;
	UCHAR	 StaffInternationalAssists;
	CHAR	 StaffJobForNation;
	CHAR	 StaffAdaptability;
	CHAR	 StaffJobForClub;
	CHAR	 StaffAmbition;
	CHAR	 StaffDetermination;
	CHAR	 StaffLoyalty;
	CHAR	 StaffPressure;
	CHAR	 StaffProfessionalism;
	CHAR	 StaffSportsmanship;
	CHAR	 StaffTemperament;
	CHAR	 StaffPlayingSquad;
	CHAR	 StaffClassification;
	CHAR	 StaffClubValuation;
	CHAR	 StaffDeclaredNation;
	CHAR	 StaffStanleyCupsWon;
	CHAR	 StaffSquadSelectedFor;
	CHAR	 StaffNationalTeamJobLevel;
	LONG	 StaffEstimatedWageWeekly;
};

long filelength;

int main() {

	fstream file ("staff.dat", ios::in | ios::out | ios::binary);

	struct STAFF fileindex;

	// Calculate the length of staff.dat:
	file.seekg (0, ios::end);
	filelength = file.tellg();
	file.seekg (0, ios::beg);

	if (file.is_open())
	{
		// Here is the loop for updating each record
		while( file.tellg() < filelength )
		{
			file.read ((char*)&fileindex, sizeof(STAFF));
			fileindex.StaffContractExpiresClub.year = fileindex.StaffContractExpiresClub.year + 1000;	// Add 1000 to the year field
						
			file.write ((char*)&fileindex, sizeof(STAFF));		// Write the changes
		}

		file.close();	// Close the file after completing the loop
	}

		cout << endl << "Press ENTER to close this window.";
		cin.get();
		return(0);

}
I thought I might add; I've been able to achieve what I want to do (i.e. update a particular element/field within each record) without using struct. I have done this by counting the number of bytes into each record the value is located and the using seekg() and seekp() to navigate to that point.

However, what I would now like to do is achieve the same thing using struct (as detailed in my first post) because when I want to update several elements/fields within a record it starts getting messy using my non-struct method.
The program should go into an infinite loop.
The problem is file.tellg() returns -1, not filelength when you get to the end of the file

You need to change
while( file.tellg() < filelength )
to
while( file.good() )
Thank you very much. I've made the change as you recommended and this allows the loop to complete.

Is there any advice anybody could give me with regards to writing the new StaffContractExpiresClub.year value for each record to the file?
Topic archived. No new replies allowed.