fstream, copy info from one file to another

Good evening gents, madams.

I have an unfinished matter with whom i'm struggling with. I'm creating program which will be like Police database with objects detainees, officers and departments. And now what i'm trying to accomplish is to edit already added record of detainee, i understand that i cant edit a record which is already written in file or can i but its out of my knowledge.

So this edit function will find detainee by code which user will enter, if the users entered code is the same like in files code it will read all of the content from file detainees.txt. I have found the detainee, entered the new information and writing this new information to new file called detaineesNEW.txt.

Now what i want to do is read all information from detainees.txt file and copy it in detaineesNEW.txt file so there would be my new edited detainee and the rest of the records which i have added in past. After i have copied content from detainees.txt file to detaineesNEW.txt i have to delete detainees.txt file and rename detaineesNEW.txt file as detainees.txt

I hope you did understand what i ment, if not please ask me and i will reply as soon as possible.

so here's my code:

Edit function
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
 void editDetainee()
{
	const int size = 10000;
	//Detain* detaineeArr = new Detain[size];
	int entry_count = 0;

	string code_input, det_code, new_det_code, n_e ;

	ifstream infileD("detainees.txt", ios::in);
	char line[220];

	while (infileD)
	{
		infileD >> line;
		if (strcmp(line, "--------------------") == 0)
		{
			entry_count++;
		}
	}
	
	cout << "size = " << entry_count;
	cout << endl;

	
	cout << " Enter the code of detainee: ";
	
	cin >> det_code;	

	while (infileD)
	{
		infileD >> detainee.code >> detainee.name >> detainee.surname >>
 detainee.detaineeReason >> detainee.captured >> detainee.released >> detainee.officer_code;
		
		if (det_code == detainee.code)
		{
			cin.ignore();
			cin.getline(detainee.code, 10);
			cin.getline(detainee.name, 20);
			cin.getline(detainee.surname, 20);
			cin.getline(detainee.detaineeReason, 100);
			cin.getline(detainee.captured, 11);
			cin.getline(detainee.released, 11);
			cin.getline(detainee.officer_code, 40);
		}

		ofstream outfileD("detaineesNEW.txt", ios::trunc);
			
				
		cout << " Enter information about detainee " << endl;

		// Entering information of detainee.
		
		cin.ignore();
		cout << " Code: ";
		cin.getline(detainee.code, 10);
		cout << " Name: ";
		cin.getline(detainee.name, 20);
		cout << " Surename: ";
		cin.getline(detainee.surname, 20);
		cout << " Reason why arested:  ";
		cin.getline(detainee.detaineeReason, 100);
		cout << " Caputre date: ";
		cin.getline(detainee.captured, 11);
		cout << " Release date: ";
		cin.getline(detainee.released, 11);
		cout << " Captured by: ";
		cin.getline(detainee.officer_code, 40);


		// Writing in file.
		
		outfileD << detainee.code << '\n';
		outfileD << detainee.name << '\n';
		outfileD << detainee.surname << '\n';
		outfileD << detainee.detaineeReason << '\n';
		outfileD << detainee.captured << '\n';
		outfileD << detainee.released << '\n';
		outfileD << detainee.officer_code << '\n';
		outfileD << "--------------------" << '\n';


		outfileD.flush();
		outfileD.close();
		infileD >> line;

		if (strcmp(line, "--------------------") == 0)
		{
			entry_count++;
		}
	}
	
}


This is how i add brand new detainees.

Add function
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
void addDetainee()
{
	
	ofstream outfileD("detainees.txt", ios::out | ios::app);

	if (!outfileD)
	{
		cerr << " Error opening file " << endl;
	}		
	else
	{
		cerr << " Please fill in the following information about detainee " << endl << endl;

		// Entering information of detainee.
		cin.ignore();
		cout << " Code: ";
		cin.getline(detainee.code, 10);
		cout << " Name: ";
		cin.getline(detainee.name, 20);
		cout << " Surename: ";
		cin.getline(detainee.surname, 20);
		cout << " Reason why arested:  ";
		cin.getline(detainee.detaineeReason, 100);
		cout << " Caputre date: ";
		cin.getline(detainee.captured, 11);
		cout << " Release date: ";
		cin.getline(detainee.released, 11);
		cout << " Captured by: ";
		cin.getline(detainee.officer_code, 40);

		// Writing in file.
		outfileD << detainee.code << '\n';
		outfileD << detainee.name << '\n';
		outfileD << detainee.surname << '\n';
		outfileD << detainee.detaineeReason << '\n';
		outfileD << detainee.captured << '\n';
		outfileD << detainee.released << '\n';
		outfileD << detainee.officer_code << '\n';
		outfileD << "--------------------" << '\n';

		outfileD.flush();
		outfileD.close();		

	}	
}


Objects which im using.

Structure
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
#ifndef STRUCTURE_H
#define STRUCTURE_H
#include <iostream>
using namespace std;

struct Detain
{	
	char code[10];
	char name[20];
	char surname[20];
	char detaineeReason[100];
	char captured[11];
	char released[11];
	char officer_code[40];

}detainee;

struct Offic
{
	char officer_code[20];
	char officer_name[20];
	char officer_surname[20];
	char officer_position[20];
	char dep_number[20];

}officer;

struct Depart
{
	char dep_number[20];
	char dep_name[20];
	char dep_description[40];
	char dep_leader[20];

}department;

#endif 


Hope you can help, thank you in advance.
Last edited on
anyone is free to help :)
Do you realize that in your editDetainee() function your detaineesNEW.txt file will have at most one record? Every time through your loop you delete the contents of the file when you re-open the file.

Next your code could use some cleanup of duplicate code. For example in several places you get a bunch of information from the user, if you placed that code into a function you could reduce the duplication. The same with the "output" sections.

Next since you're using getline() when retrieving the information from the user you should be using getline() to get the information from the file. Remember getline() can have spaces embedded within the string whereas the extraction operator stops processing the string when it encounters a whitespace character. Speaking of strings why are you using C-strings instead of C++ strings?

And remember you can't use the comparison operator to compare C-strings.

"Do you realize that in your editDetainee() function your detaineesNEW.txt file will have at most one record? Every time through your loop you delete the contents of the file when you re-open the file."

I ment like that, so it would store only one record, and after its edited i want to copy everything from detainees.txt to detaineesNEW.txt and then rename detaineesNEW to detainees. Or if you have better option please tell me,

"Next your code could use some cleanup of duplicate code. For example in several places you get a bunch of information from the user, if you placed that code into a function you could reduce the duplication. The same with the "output" sections."

We haven't touched functions yet, so im not aware of how it is done, but i you would like to show me i would appreciate it.

"Next since you're using getline() when retrieving the information from the user you should be using getline() to get the information from the file. Remember getline() can have spaces embedded within the string whereas the extraction operator stops processing the string when it encounters a whitespace character. Speaking of strings why are you using C-strings instead of C++ strings?"

so instead of this while (infileD >> detainee.code >> detainee.name >> detainee.surname >> detainee.detaineeReason >> detainee.captured >> detainee.released >> detainee.officer_code)

i should read info. from file like this getline(infileD, detainee.code) ?

I used c strings because i didnt know kinda how to work with c++, with c++ you dont have to define seize, so this troubled me a little bit, and didn't know how to deal with them.
We haven't touched functions yet, so im not aware of how it is done, but i you would like to show me i would appreciate it.

Then what do you call this:
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
void addDetainee()
{
	
	ofstream outfileD("detainees.txt", ios::out | ios::app);

	if (!outfileD)
	{
		cerr << " Error opening file " << endl;
	}		
	else
	{
		cerr << " Please fill in the following information about detainee " << endl << endl;

		// Entering information of detainee.
		cin.ignore();
		cout << " Code: ";
		cin.getline(detainee.code, 10);
		cout << " Name: ";
		cin.getline(detainee.name, 20);
		cout << " Surename: ";
		cin.getline(detainee.surname, 20);
		cout << " Reason why arested:  ";
		cin.getline(detainee.detaineeReason, 100);
		cout << " Caputre date: ";
		cin.getline(detainee.captured, 11);
		cout << " Release date: ";
		cin.getline(detainee.released, 11);
		cout << " Captured by: ";
		cin.getline(detainee.officer_code, 40);

		// Writing in file.
		outfileD << detainee.code << '\n';
		outfileD << detainee.name << '\n';
		outfileD << detainee.surname << '\n';
		outfileD << detainee.detaineeReason << '\n';
		outfileD << detainee.captured << '\n';
		outfileD << detainee.released << '\n';
		outfileD << detainee.officer_code << '\n';
		outfileD << "--------------------" << '\n';

		outfileD.flush();
		outfileD.close();		

	}	
}


I'd call it a function, what do you call it?

I ment like that, so it would store only one record, and after its edited i want to copy everything from detainees.txt to detaineesNEW.txt and then rename detaineesNEW to detainees. Or if you have better option please tell me,

But you never copy anything to detainees.txt so you lose the information. You need to write the unchanged information that occurs before the record you want to change into the "new" file, then modify the information in the incorrect record, then write it to the "new" file, then copy the rest of the information into the "new" file. Finally after completely writing the information to the new file, close both files, properly rename the "new" file to the original file name.


I used c strings because i didnt know kinda how to work with c++, with c++ you dont have to define seize, so this troubled me a little bit, and didn't know how to deal with them.

The fact that you don't need to worry about the "size" of a C++ string is one of the best reasons to use them. A C++ takes care of the size it's self and is much safer that C-strings. Also there are many other member functions that make using a C++ string much safer and easier to use than those old fashioned C-strings.
i should read info. from file like this getline(infileD, detainee.code) ?

As long as you're using C++ strings, yes. If you're using C-strings then there is another version of getline() that you should use.




Topic archived. No new replies allowed.