Reading from Binary File to Structure Array

I am having trouble reading information from a binary file into a dynamically allocated array of structures. Later I will have to save the entire array back into the same file in a different function, but for now I am having trouble trying to get the information out of the file before I do anything else.

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
struct CustomerAccountRecords
{
	string fullName, lastName;
	string streetAddress, city, state;
	int zipCode = 0,lastPaymentDate = 0;
	long long int phoneNumber = 0;
	double accountBalance = 0;
};

int main()
{
	CustomerAccountRecords *recordPtr = nullptr;
	recordPtr = new CustomerAccountRecords[100];
	int choice = 0, numRecords = 0;
	fstream RecordFile;
	
	RecordFile.open("CustomerRecords.dat", ios::in | ios::binary);
	if (!RecordFile) {
		cout << "Error opening file. File either does not exist or failed to open." << endl;
	}
	else {
		while (!RecordFile.eof()) {
			recordPtr[numRecords] = RecordFile.read(reinterpret_cast<char*>(&recordPtr), sizeof(recordPtr));
			numRecords++;
		}
	}

	do {
		cout << endl;
		choice = Menu();
		switch (choice) {
		case 1: 
			NewCustomerRecord(recordPtr, numRecords);
			numRecords++;
			SortRecords(recordPtr, numRecords);
			break;
		case 2: 
			DisplayCustomerRecord(recordPtr, numRecords);
			break;
		case 3: 
			DeleteCustomerRecord(recordPtr, numRecords);
			numRecords--;
			break;
		case 4: 
			EditCustomerRecord(recordPtr, numRecords);
			SortRecords(recordPtr, numRecords);
			break;
		case 5: 
			DisplayAllRecords(recordPtr, numRecords);
			break;
		case 6: 
			SaveCustomerRecords(RecordFile, recordPtr, numRecords);
			break;
		}
	} while (choice < 6 || choice > 0);

	delete[] recordPtr;
	RecordFile.close();

	return 0;
}
Are you absolutely sure it's a binary file? Try opening it in a text editor. If you can easily read the numbers then it's not binary.

If it is a binary file, then what is its exact structure? For instance, you can't just read a string in from a binary file. You need some way of knowing how long the string is, either by storing a fixed length string, storing it's length before the string data, or by storing a "sentinel" character after it (such as '\0').
Last edited on
Yes, it has to be a binary file. We were taught to read from and write to binary files by using the reinterpret_cast. The format would be "file.write(reinterpret_cast<char*>(&object), sizeof(object));". I am attempting to do that now, and my code currently looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
RecordFile.open("CustomerRecords.dat", ios::in | ios::binary);
	if (!RecordFile) {
		cout << "Error opening file. File either does not exist or failed to open." << endl;
	}
	else {
		while (!RecordFile.eof()) {
			RecordFile.read(reinterpret_cast<char*>(&recordPtr), sizeof(recordPtr));
			recordPtr[numRecords].fullName = recordPtr->fullName;
			recordPtr[numRecords].streetAddress = recordPtr->streetAddress;
			recordPtr[numRecords].city = recordPtr->city;
			recordPtr[numRecords].state = recordPtr->state;
			recordPtr[numRecords].zipCode = recordPtr->zipCode;
			recordPtr[numRecords].phoneNumber = recordPtr->phoneNumber;
			recordPtr[numRecords].accountBalance = recordPtr->accountBalance;
			recordPtr[numRecords].lastPaymentDate = recordPtr->lastPaymentDate;
			recordPtr[numRecords].lastName = recordPtr[numRecords].fullName.substr(0, recordPtr[numRecords].fullName.find(" "));
			numRecords++;
		}
	}


to get the information from the binary file into the array. I am about to attempt running it for the first time, but if you see any issues already, please let me know.
Now it's creating an extra structure with the initialized values.



Select a number from the menu below:
1. Create a new customer record?
2. Display an existing customer record?
3. Delete an existing customer record?
4. Edit an existing customer record?
5. Display all existing customer records?
6. Save all existing customer records and exit?
5

Name:
Street Address:
City:
State:
ZIP:     0
Telephone Number:          0
Account Balance: $0.00
Date of Last Payment: 00000000


Select a number from the menu below:
1. Create a new customer record?
2. Display an existing customer record?
3. Delete an existing customer record?
4. Edit an existing customer record?
5. Display all existing customer records?
6. Save all existing customer records and exit?
1
Enter New Customer Account Information Below:
Full Name (First Last): Lauren Kate
Street Address: 1319 Amber Drive
City: Huntsville
State: Alabama
ZIP Code (NNNNN): 35602
Telephone Number (NNNNNNNNNN): 2565098677
Account Balance: $1200
Date of Last Payment (MMDDYYYY): 02042000

Account Information has been saved.

Select a number from the menu below:
1. Create a new customer record?
2. Display an existing customer record?
3. Delete an existing customer record?
4. Edit an existing customer record?
5. Display all existing customer records?
6. Save all existing customer records and exit?
5

Name:
Street Address:
City:
State:
ZIP: 00000
Telephone Number: 0000000000
Account Balance: $0.00
Date of Last Payment: 00000000


Name: Lauren Kate
Street Address: 1319 Amber Drive
City: Huntsville
State: Alabama
ZIP: 35602
Telephone Number: 2565098677
Account Balance: $1200.00
Date of Last Payment: 02042000


Select a number from the menu below:
1. Create a new customer record?
2. Display an existing customer record?
3. Delete an existing customer record?
4. Edit an existing customer record?
5. Display all existing customer records?
6. Save all existing customer records and exit?
2
Enter the full name of the customer whose file you would like displayed (First Last): Lauren Kate

Name: Lauren Kate
Street Address: 1319 Amber Drive
City: Huntsville
State: Alabama
ZIP: 35602
Telephone Number: 2565098677
Account Balance: $1200.00
Date of Last Payment: 02042000


Select a number from the menu below:
1. Create a new customer record?
2. Display an existing customer record?
3. Delete an existing customer record?
4. Edit an existing customer record?
5. Display all existing customer records?
6. Save all existing customer records and exit?
1
Enter New Customer Account Information Below:
Full Name (First Last): Debbie Dodd
Street Address: 1319 Amber Dr.
City: Huntsville
State: AL
ZIP Code (NNNNN): 35602
Telephone Number (NNNNNNNNNN): 2565098888
Account Balance: $3333
Date of Last Payment (MMDDYYYY): 01012019

Account Information has been saved.

Select a number from the menu below:
1. Create a new customer record?
2. Display an existing customer record?
3. Delete an existing customer record?
4. Edit an existing customer record?
5. Display all existing customer records?
6. Save all existing customer records and exit?
5

Name:
Street Address:
City:
State:
ZIP: 00000
Telephone Number: 0000000000
Account Balance: $0.00
Date of Last Payment: 00000000


Name: Debbie Dodd
Street Address: 1319 Amber Dr.
City: Huntsville
State: AL
ZIP: 35602
Telephone Number: 2565098888
Account Balance: $3333.00
Date of Last Payment: 01012019


Name: Lauren Kate
Street Address: 1319 Amber Drive
City: Huntsville
State: Alabama
ZIP: 35602
Telephone Number: 2565098677
Account Balance: $1200.00
Date of Last Payment: 02042000


Select a number from the menu below:
1. Create a new customer record?
2. Display an existing customer record?
3. Delete an existing customer record?
4. Edit an existing customer record?
5. Display all existing customer records?
6. Save all existing customer records and exit?
1
Enter New Customer Account Information Below:
Full Name (First Last): Johnny Barnard
Street Address: 120 Sycamore Road
City: Maysville
State: AL
ZIP Code (NNNNN): 35748
Telephone Number (NNNNNNNNNN): 2567018888
Account Balance: $1
Date of Last Payment (MMDDYYYY): 07152001

Account Information has been saved.

Select a number from the menu below:
1. Create a new customer record?
2. Display an existing customer record?
3. Delete an existing customer record?
4. Edit an existing customer record?
5. Display all existing customer records?
6. Save all existing customer records and exit?
5

Name:
Street Address:
City:
State:
ZIP: 00000
Telephone Number: 0000000000
Account Balance: $0.00
Date of Last Payment: 00000000


Name: Johnny Barnard
Street Address: 120 Sycamore Road
City: Maysville
State: AL
ZIP: 35748
Telephone Number: 2567018888
Account Balance: $1.00
Date of Last Payment: 07152001


Name: Debbie Dodd
Street Address: 1319 Amber Dr.
City: Huntsville
State: AL
ZIP: 35602
Telephone Number: 2565098888
Account Balance: $3333.00
Date of Last Payment: 01012019


Name: Lauren Kate
Street Address: 1319 Amber Drive
City: Huntsville
State: Alabama
ZIP: 35602
Telephone Number: 2565098677
Account Balance: $1200.00
Date of Last Payment: 02042000


Select a number from the menu below:
1. Create a new customer record?
2. Display an existing customer record?
3. Delete an existing customer record?
4. Edit an existing customer record?
5. Display all existing customer records?
6. Save all existing customer records and exit?

I'm getting an exception thrown at this line:

1
2
			recordPtr[numRecords].zipCode = recordPtr->zipCode;
Yes, it has to be a binary file.

Then what is the structure?
Is it up to you?
If so, then how did you write the data in the first place?
You cannot simply write and read a std::string with the .write() and .read() methods, even though it might seem to work due to "short string optimization" (where the char data is stored directly in the string structure).
So,
are you storing fixed length strings?
are you storing the string length before the data?
are you storing a sentinel (such as '\0') after the string data?

The reason you are getting an extra empty record is that you are not detecting eof properly, but we can fix that later.

The line you are getting an error on is crazy. recordPtr can't be two different things at the same time. Presumably you mean to have a different struct to read into from the file. But again, there's a lot of other problems besides this.
Last edited on
Last edited on
This is the assignment description:

Function main will call other program functions.
Write a program that uses a structure to store the following data about a customer account:
Name ( firstName space lastName stored in a single variable)
Address
City, State, and ZIP
Telephone Number
Account Balance
Date of Last Payment
The structure should be used to store customer account records. The program should have a menu that lets the user perform the following operations: (the following menu items should be broken into functions)
Enter new customer record
Stored in a dynamic memory array
Input Validation: Be sure the user enters data for all fields. No negative account balances should be entered.
newly entered records should be inserted into the array in alphabetical order by last name.
Search for a particular customer's record and display it
Search for a particular customer's record and delete it
Search for a particular customer's record and change it
Display all the customer records
Save the customer records to a file and exit

NOTE: When the program begins read all the existing customers from the file into the structure array.
I have changed the code significantly, but thank you for your help.
Your assignment doesn't say anything about a binary file.
If you can use a text file it will be easier.
I assume that's what you are doing now.

If you are still using a binary file, then try it with a long name, like Frederick Wolfeschlegelsteinhausenbergerdorff.
I have changed it so that instead of strings, I am using character arrays. That way I can save them into a binary file. I've almost got it working, except I can't seem to arrange the structures in alphabetical order by last name.
Topic archived. No new replies allowed.