Read from a text file and then write into a binary file

CAN NOT USE VECTORS

In this program I have to read a text file and write into a binary file. when writing into the binary file, the number of Persons should be written first, followed by the whole struct array.

however, I can't get my code to read the names of the testers correctly. and when i run the program, it doesn't show anything else after i open the binary file. Am I writing into the binary file correctly? Here is my code as of right now:

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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

#include<fstream>
#include<string>
#include<iostream>
using namespace std;


struct Date
{
	int day;
	int month;
	int year;
};

struct Person
{
	char name[20];
	double score;
	Date testTaken;
};


int main()
{
	Person *someone;
	string fileT,
		fileB;
	int num = 0;

	cout << "Enter the name of the file with the testers information:\n";
	cin >> fileT;

	cout << "Enter the name of the binary file:\n";
	cin >> fileB;

	cout << "I will now attempt to open and read the text file.\n";
	someone = readTesters(fileT, num);

	cout << "I will now attempt to to write the text file data into a binary file.\n";
	writeTesters(fileT, fileB, someone, num);

	return 0;
}


Person* readTesters(const string& fileTxt, int& num)
{
	int numP;
	fstream inFile;

	inFile.open(fileTxt, ios::in);

	if (inFile.fail())
	{
		cout << "Error opening testers file!\n";
	}
	else if (inFile)
	{
		string score,
			name,
			day,
			month,
			year;
		cout << "Testers file opened. Now reading file...\n";
		inFile >> numP;
		Person *people = new Person[numP];
		while (inFile)
		{
			for (int i = 0; i < numP; i++)
			{
				inFile.getline(people[i].name, 20, '\n');  //not reading the names correctly  
				getline(inFile, score, ',');
				people[i].score = atof(score.c_str());
				getline(inFile, day, '/');
				people[i].testTaken.day = atoi(day.c_str());
				getline(inFile, month, '/');
				people[i].testTaken.month = atoi(month.c_str());
				getline(inFile, year);
				people[i].testTaken.year = atoi(year.c_str());
			}
		}
		num = numP;
		inFile.close();

		return people;
	}
}


void writeTesters(const string& fileTxt, const string& fileDat, Person people[], int numP) 
{
	fstream file;
	char newline = '\n';
	char slash = '/';

	file.open(fileDat, ios::out | ios::binary);

	if (file.fail())
	{
		cout << "Error opening binary file!\n";
	}

	else if (file)
	{
		cout << "File opened. Now writing data into file...\n"; //when i run the program, this is as far as it goes. it doesnt show anything else
		for (int i = 0; i < numP; i++)
		{
			file.write(reinterpret_cast<char *>(numP), sizeof(numP));
			file.write(reinterpret_cast<char *>(newline), sizeof(newline));
			file.write(reinterpret_cast<char *>(people[i].name), sizeof(people[i].name));
			file.write(reinterpret_cast<char *>(newline), sizeof(newline));
			file.write(reinterpret_cast<char *>(&people[i].score), sizeof(people[i].score));
			file.write(reinterpret_cast<char *>(newline), sizeof(newline));
			file.write(reinterpret_cast<char *>(people[i].testTaken.day), sizeof(people[i].testTaken.day));
			file.write(reinterpret_cast<char *>(slash), sizeof(slash));
			file.write(reinterpret_cast<char *>(people[i].testTaken.month), sizeof(people[i].testTaken.month));
			file.write(reinterpret_cast<char *>(slash), sizeof(slash));
			file.write(reinterpret_cast<char *>(people[i].testTaken.month), sizeof(people[i].testTaken.month));
			file.write(reinterpret_cast<char *>(newline), sizeof(newline));
		}

		cout << "Data written into file.\n\n";
	}

	cout << "Now closing the file...\n";
	file.close();

	cout << "Opening the file again for input in binary mode...\n";
	file.open(fileDat, ios::in | ios::binary);

	cout << "Now reading the data back into memory...\n";
	for (int i = 0; i < numP; i++)
	{
		file.read(reinterpret_cast<char *>(numP), sizeof(numP));
		file.read(reinterpret_cast<char *>(newline), sizeof(newline));
		file.read(reinterpret_cast<char *>(people[i].name), sizeof(people[i].name));
		file.read(reinterpret_cast<char *>(newline), sizeof(newline));
		file.read(reinterpret_cast<char *>(&people[i].score), sizeof(people[i].score));
		file.read(reinterpret_cast<char *>(newline), sizeof(newline));
		file.read(reinterpret_cast<char *>(people[i].testTaken.day), sizeof(people[i].testTaken.day));
		file.read(reinterpret_cast<char *>(slash), sizeof(slash));
		file.read(reinterpret_cast<char *>(people[i].testTaken.month), sizeof(people[i].testTaken.month));
		file.read(reinterpret_cast<char *>(slash), sizeof(slash));
		file.read(reinterpret_cast<char *>(people[i].testTaken.month), sizeof(people[i].testTaken.month));
		file.read(reinterpret_cast<char *>(newline), sizeof(newline));
	}

	cout << "Here is what I stored in the binary file:\n";
	for (int i = 0; i < numP; i++)
	{
		cout << "Tester #" << (i + 1) << endl;
		cout << "Name: " << people[i].name << endl;
		cout << "Score: " << people[i].score << endl;
		cout << "Test Date: " << people[i].testTaken.day << "/" << people[i].testTaken.month
			<< "/" << people[i].testTaken.year << endl << endl;
	}

	file.close();
}
Show us your input file.

And your binary file writing is all wrong.

This is basically all you need. No loops, no piecewise member twiddling.
file.write(reinterpret_cast<char *>(people), sizeof(Person)*numP);

OK, that would be a bit rough on the file reader, so perhaps two lines.
1
2
file.write(reinterpret_cast<char *>(&nump), sizeof(numP));
file.write(reinterpret_cast<char *>(people), sizeof(Person)*numP);


Then reader is
1
2
3
4
int numP;
file.read(reinterpret_cast<char *>(&nump), sizeof(numP));
Person *people = new Person[numP];
file.read(reinterpret_cast<char *>(people), sizeof(Person)*numP);


Binary files are just the data. Writing presentation details like spaces, newlines and slashes makes no sense. If you want those things, it's a text file.
Last edited on
Wow thank you I really misunderstood that part. I updated my program but now I still can't get it to properly read the testers name and scores.

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

Person* readTesters(const string& fileTxt, int& num)
{
	int numP;
	fstream inFile;

	inFile.open(fileTxt, ios::in);

	if (inFile.fail())
	{
		cout << "Error opening testers file!\n";
	}
	else if (inFile)
	{
		string score,
			name,
			day,
			month,
			year;
		cout << "Testers file opened. Now reading file...\n";
		inFile >> numP;
		Person *people = new Person[numP];
		while (inFile)
		{
			for (int i = 0; i < numP; i++)
			{
				inFile.getline(people[i].name, 20, '\n');    //not reading their name
				getline(inFile, score, ',');
				people[i].score = atof(score.c_str());       //reads 0.0 for their scores
				getline(inFile, day, '/');
				people[i].testTaken.day = atoi(day.c_str());
				getline(inFile, month, '/');
				people[i].testTaken.month = atoi(month.c_str());
				getline(inFile, year);
				people[i].testTaken.year = atoi(year.c_str());
			}
		}
		num = numP;
		inFile.close();

		return people;
	}
}

//**************************************************************************************************

void writeTesters(const string& fileTxt, const string& fileDat, Person people[], int numP)
{
	fstream file;

	file.open(fileDat, ios::out | ios::binary);

	if (file.fail())
	{
		cout << "Error opening binary file!\n";
	}

	else if (file)
	{
		cout << "File opened. Now writing data into file...\n";   //stops after this
		for (int i = 0; i < numP; i++)
		{
			file.write(reinterpret_cast<char *>(&numP), sizeof(numP));
			file.write(reinterpret_cast<char *>(people), sizeof(Person)*numP);
		}

		cout << "Data written into file.\n\n";
	}

	cout << "Now closing the file...\n";
	file.close();

	cout << "Opening the file again for input in binary mode...\n";
	file.open(fileDat, ios::in | ios::binary);

	cout << "Now reading the data back into memory...\n";
	for (int i = 0; i < numP; i++)
	{
		file.read(reinterpret_cast<char *>(&numP), sizeof(numP));
		Person *people = new Person[numP];
		file.read(reinterpret_cast<char *>(people), sizeof(Person)*numP);
	}

	cout << "Here is what I stored in the binary file:\n";
	for (int i = 0; i < numP; i++)
	{
		cout << "Tester #" << (i + 1) << endl;
		cout << "Name: " << people[i].name << endl;
		cout << "Score: " << people[i].score << endl;
		cout << "Test Date: " << people[i].testTaken.day << "/" << people[i].testTaken.month
			<< "/" << people[i].testTaken.year << endl << endl;
	}

	file.close();
}
Also here is the file I am reading from. Note that their score and test date are separated by a comma and not a space.


10
Sue Smith
56.8,10/11/2018
John Jones
86.9,09/11/2018
Li Ying
95.0,08/08/2018
Kun Joom
93.5,07/07/2018
Joe Bush
75.0,03/12/2018
Kim Long
65.3,02/12/2018
Fred Ring
33.3,19/05/2019
Frank Pearse
67.8,23/03/2018
Helen Hu
88.8,25/08/2018
Mark James
76.0,26/11/2019
There are no loops.

1
2
3
4
5
	for (int i = 0; i < numP; i++)
		{
			file.write(reinterpret_cast<char *>(&numP), sizeof(numP));
			file.write(reinterpret_cast<char *>(people), sizeof(Person)*numP);
		}


It's just two lines.
1
2
			file.write(reinterpret_cast<char *>(&numP), sizeof(numP));
			file.write(reinterpret_cast<char *>(people), sizeof(Person)*numP);

Boom - done!


Same with reading.
1
2
3
	file.read(reinterpret_cast<char *>(&numP), sizeof(numP));
		Person *people = new Person[numP];
		file.read(reinterpret_cast<char *>(people), sizeof(Person)*numP);
Thank you. I fixed the loop but I'm still having trouble reading the file. Here is my code now:

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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include<fstream>
#include<string>
#include<iostream>
#include<cstdlib>
using namespace std;


struct Date
{
	int day;
	int month;
	int year;
};

struct Person
{
	char name[20];
	double score;
	Date testTaken;
};


Person* readTesters(const string& fileTxt, int& num);
void writeTesters(const string& fileTxt, const string& fileDat, Person people[], int numP);

int main()
{
	Person *someone;
	string fileT,
		fileB;
	int num = 0;

	cout << "Enter the name of the file with the testers information:\n";
	cin >> fileT;

	cout << "Enter the name of the binary file:\n";
	cin >> fileB;

	cout << "I will now attempt to open and read the text file.\n";
	someone = readTesters(fileT, num);

	cout << "I will now attempt to to write the text file data into a binary file.\n";
	writeTesters(fileT, fileB, someone, num);

	return 0;
}


Person* readTesters(const string& fileTxt, int& num)
{
	int numP;
	fstream inFile;

	inFile.open(fileTxt, ios::in);

	if (inFile.fail())
	{
		cout << "Error opening testers file!\n";
	}
	else if (inFile)
	{
		string score,
			day,
			month,
			year;
		cout << "Testers file opened. Now reading file...\n";
		inFile >> numP;
		cin.ignore();
		Person *people = new Person[numP];
		while (inFile)
		{
			for (int i = 0; i < numP; i++)
			{
				inFile.getline(people[i].name, 20, '\n');    //not reading their name
				getline(inFile, score, ',');
				people[i].score = atof(score.c_str());       
				getline(inFile, day, '/');
				people[i].testTaken.day = atoi(day.c_str());
				getline(inFile, month, '/');
				people[i].testTaken.month = atoi(month.c_str());
				getline(inFile, year);
				people[i].testTaken.year = atoi(year.c_str());
				  //does not read their name
				  //everyone's score is the same?
				  //everyone's test date is the same
			}
		}
		num = numP;
		inFile.close();

		return people;
	}
}


void writeTesters(const string& fileTxt, const string& fileDat, Person people[], int numP)
{
	fstream file;

	file.open(fileDat, ios::out | ios::binary);

	if (file.fail())
	{
		cout << "Error opening binary file!\n";
	}

	else if (file)
	{
		cout << "File opened. Now writing data into file...\n";   

		file.write(reinterpret_cast<char *>(&numP), sizeof(numP));
		file.write(reinterpret_cast<char *>(people), sizeof(Person)*numP);

		cout << "Data written into file.\n\n";
	}

	cout << "Now closing the file...\n";
	file.close();

	cout << "Opening the file again for input in binary mode...\n";
	file.open(fileDat, ios::in | ios::binary);

	cout << "Now reading the data back into memory...\n";
	
	file.read(reinterpret_cast<char *>(&numP), sizeof(numP));
	file.read(reinterpret_cast<char *>(people), sizeof(Person)*numP);

	cout << "Here is what I stored in the binary file:\n";
	for (int i = 0; i < numP; i++)
	{
		cout << "Tester #" << (i + 1) << endl;
		cout << "Name: " << people[i].name << endl;
		cout << "Score: " << people[i].score << endl;
		cout << "Test Date: " << people[i].testTaken.day << "/" << people[i].testTaken.month
			<< "/" << people[i].testTaken.year << endl << endl;
	}

	file.close();
}
I'm losing my mind over this program! All I need is to properly read the text file.
Change line 68
cin.ignore();
to
inFile.ignore(1000,'\n');


Remove lines 70 and 71:
1
2
		while (inFile)
		{

and the corresponding close brace on line 87


This produces what I assume you want:
Enter the name of the file with the testers information: test.dat
Enter the name of the binary file: test.bin
I will now attempt to open and read the text file.
Testers file opened. Now reading file...
I will now attempt to to write the text file data into a binary file.
File opened. Now writing data into file...
Data written into file.

Now closing the file...
Opening the file again for input in binary mode...
Now reading the data back into memory...
Here is what I stored in the binary file:
Tester #1
Name: Sue Smith
Score: 56.8
Test Date: 10/11/2018

Tester #2
Name: John Jones
Score: 86.9
Test Date: 9/11/2018

Tester #3
Name: Li Ying
Score: 95
Test Date: 8/8/2018

Tester #4
Name: Kun Joom
Score: 93.5
Test Date: 7/7/2018

Tester #5
Name: Joe Bush
Score: 75
Test Date: 3/12/2018

Tester #6
Name: Kim Long
Score: 65.3
Test Date: 2/12/2018

Tester #7
Name: Fred Ring
Score: 33.3
Test Date: 19/5/2019

Tester #8
Name: Frank Pearse
Score: 67.8
Test Date: 23/3/2018

Tester #9
Name: Helen Hu
Score: 88.8
Test Date: 25/8/2018

Tester #10
Name: Mark James
Score: 76
Test Date: 26/11/2019



You need to start outputting debug data for the things you read.
Topic archived. No new replies allowed.