2 questions about files

For some reason when I use the following code, all the Person's in my file get NULL'ed up to the one being written. Any ideas what's wrong with the following:


1
2
3
4
	dFile.open("persons.bin", ios::out, ios::binary);
	dFile.seekp((sizeof(Person) * id), ios::beg);
	dFile.write((char *) &p, sizeof(Person));
	dFile.close();


Second question is, is there a way to store the current cursor position into an integer?
What is the p object? Does it point to something valid? What is the Person type? Is it a POD type? Please show a complete program that demonstrates the problem. There is no way to tell what is wrong looking only at that small chunk of code.

tellp tells where the current position is. It is easy to story the return value to a variable. It is a common technique for determining a file size. Seek to the end and then use tellp to indicate how many bytes are within the file.
1. By default, files are truncated when opened. To prevent this, open with the flag std::ios::app (IINM). In your case, that would be std::ios::binary|std::ios::app.
1. What kempofighter said.
2. std::fstream::tellp() and std::fstream::tellg(). One returns the writing position, and the other the reading position.
Last edited on
A Person

1
2
3
4
5
class Person {
public:
char fName[100], lName[100], addy[200], gend;
int age;
};


I cannot use append, because I need to overwrite a certain Person in the file not add to the end. The file contains x number of records each one is located by multiplying sizeof(Person) by the record of the person in the file (records are sequential from 0).

My file is writing and reading the records fine but when I try to modify an existing record it doesn't delete the records it just NULLS everything until the point to be written. It's very frustrating...I've tried everything I can think of.
In that case, I was right. Without std::ios::app, the file is truncated. You're not forced to add something at the end. The flag just means "don't blank the file when I open it".
I did as you said and changed it to this:

1
2
3
4
	mFile.open("persons.bin", ios::binary | ios::out | ios::app);
	mFile.seekp((sizeof(Person) * id), ios::beg);
	mFile.write((char *) &p, sizeof(Person));
	mFile.close();


At least it's not NULL'ing everything but instead it still adds the modified Person to the end of the file instead of where the pointer is. Any ideas???
 
mFile.open("persons.bin", ios::out | ios::binary);

You are still playing with fire by reading/writing a class directly to file.
no luck, still NULL'ing everything above the one being edited. I know I'm playing with fire but this is the way our teacher has asked us to do this assignment stating he'll teach us a better method later. I've spent a lot of time debugging this issue and I'm at a loss hoping you guys will have some insight. I really appreciate the help thus far.
update: not only is it NULL'ing everyting, it's still putting the edited person at the end of the file...
What is the value of id? I can't stress enough how important it is to provide a complete program. Everyone is taking Scientific Wild Ass Guesses (SWAGs) as to what you might be doing. Sometimes SWAGs are pretty close to being correct and sometimes they aren't. Just put together a simple main and show as something that we can compile and try out. Unfortunately I don't think that you can attach a file but seeing something more complete would be very helpful.
You could try storing sizeof(Person) into a variable and see if the value makes sense. I have never seen file io done like that before but I can't imagine what the problem is without a complete example.
Last edited on
OK here's my entire code, it's not completely implemented yet but it compiles and will let you try and find the bug.

person.h
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
#ifndef HEAD
#define HEAD

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

class Person //ID is stored by position in file
{
public:
	char fName[100], lName[100], addy[200], gend;
	int age;
};

void CreateFile();

void AddPerson();

void PrintDB();

void DeletePerson();

void ModifyPerson();


#endif; 


person.cpp:
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
#include "person.h"

void CreateFile()
{
	fstream cFile;
	cFile.open("persons.bin", ios::in, ios::binary);
	if (cFile.fail())
	{
		cFile.open("persons.bin", ios::out, ios::binary);
		cout << "The file was created successfully" << endl << endl;
	}
	else
	{
		cout << "The database file already exists" << endl << endl;
	}
}

void AddPerson()
{
	fstream wFile;
	Person p;
	//Get info
	cout << "Enter the first name: ";
	cin >> p.fName;
	cout << "Enter the last name: ";
	cin >> p.lName;
	cout << "Enter the age: ";
	cin >> p.age;
	cout << "Enter gender (M or F): ";
	cin >> p.gend;
	cout << "Enter address: ";
	cin.ignore();
	cin.getline(p.addy, 199);

	wFile.open("persons.bin", ios::app, ios::binary);
	wFile.seekp(0, ios::end);
	wFile.write((char *) &p, (sizeof(Person)));
	wFile.close();
	cout << "Person was added successfully" << endl << endl;
}

void PrintDB() //INCOMPLETE
{
	fstream pFile;
	Person p;
	int k = 0;

	pFile.open("persons.bin", ios::in, ios::binary);
	while (!pFile.eof())
	{
		pFile.seekg((sizeof(Person)*k), ios::beg);
		pFile.read((char *) &p, sizeof(Person));
		cout << k << ", " << p.fName << ", " << p.lName << ", " << p.gend << ", " << p.age  << ", " << p.addy << endl;
		k++;
	}
	pFile.close();
}

void DeletePerson()  //INCOMPLETE
{
	Person p;
	int id;
	fstream dFile;

	strcpy(p.fName, "{EMPTY}");
	strcpy(p.lName, "{EMPTY}");
	strcpy(p.addy, "{EMPTY}");
	p.age = 0;
	p.gend = '?';

	cout << "Enter ID of person to delete: ";
	cin >> id;
	
	dFile.open("persons.bin", ios::out, ios::binary);
	dFile.seekp((sizeof(Person) * id), ios::beg);
	dFile.write((char *) &p, sizeof(Person));
	dFile.close();
	cout << "The person was deleted successfully" << endl << endl;
}

void ModifyPerson()  //INCOMPLETE
{
	Person p;
	int id;
	fstream mFile;

	cout << "Enter ID of person to modify: ";
	cin >> id;
	cout << "Enter the first name: ";
	cin >> p.fName;
	cout << "Enter the last name: ";
	cin >> p.lName;
	cout << "Enter the age: ";
	cin >> p.age;
	cout << "Enter gender (M or F): ";
	cin >> p.gend;
	cout << "Enter address: ";
	cin.ignore();
	cin.getline(p.addy, 199);
	
	mFile.open("persons.bin", ios::out | ios::binary);
	mFile.seekp((sizeof(Person) * id), ios::beg);
	mFile.write((char *) &p, sizeof(Person));
	mFile.close();
}


main program:
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
#include "person.h"

int main()
{
	char choice = '\0';

	while (choice != 'Q')
	{
		//show menu
		cout << "MENU:    (C)reate a new empty file (if one doesn't already exist)" << endl;
		cout << "         (A)dd a person to end of database" << endl;
		cout << "         (D)elete a person by ID" << endl;
		cout << "         (M)odify a person by ID" << endl;
		cout << "         (P)rint database info" << endl;
		cout << "         (Q)uit program" << endl;
		cout << ">:";
		cin >> choice;

		switch (choice)
		{
		case 'c':
		case 'C':
			CreateFile();
			break;
		case 'a':
		case 'A':
			AddPerson();
			break;
		case 'd':
		case 'D':
			DeletePerson();
			break;
		case 'm':
		case 'M':
			ModifyPerson();
			break;
		case 'p':
		case 'P':
			PrintDB();
			break;
		case 'q':
		case 'Q':
			choice = 'Q';
			break;
		default:
			cout << "You have entered an invalid choice" << endl << endl;
			break;
		}
	}

	return 0;
}
You need to press C first before anything else to create the binary file otherwise the other functions will not work.
This is why I tried to avoid posting all my code because it scares ppl off and I get no help. Either way I finally figured out the problem, The line needed ios::in flag also.
Topic archived. No new replies allowed.