944,188 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Unsolved
  • Views: 2783
  • C++ RSS
May 20th, 2005
0

Need help with my console database app, program reading or writing incorrectly

Expand Post »
I'm developing a small database application that can add records to a file, but also modify them in a few ways. It keeps the records in a temporary object of my class PersonInfo.
The problem now is that it doesn't want to display things correctly, it seems to only be able to save the last record, then it replaces the previous records with weird characters.

OK, this is my code:

The PersonInfo class header file


#ifndef _PERSONINFO_H_
#define _PERSONINFO_H_

class PersonInfo {
private:
string name, city, country;
int age;
public:
PersonInfo();
~PersonInfo();
void DisplayDatabase(int ct);
void DisplayChangedDatabase(int ct, int whoHasStar);
void ChangePersonData(string Name, int Age, string City, string Country);

};

#endif



The PersonInfo class declaration file


#include <iostream>

using namespace std;

#include <iomanip>
#include <string>
#include "personInfo.h"


PersonInfo:ersonInfo() {
}

PersonInfo::~PersonInfo() {
}

void PersonInfo:: DisplayDatabase(int ct) {
int checkCtValue;

if (ct > 8)
checkCtValue = 19;
else
checkCtValue = 20;

cout << (ct + 1) << ": " << setw(checkCtValue) << name
<< setw(6) << age << setw(18) << city
<< setw(18) << country << "\n";
}

void PersonInfo:: DisplayChangedDatabase(int ct, int whoHasStar) {
int checkCtValue, starOff;

if (ct > 8)
checkCtValue = 19;
else
checkCtValue = 20;

cout << (ct + 1) << ": " << setw(checkCtValue) << name;

if ((ct + 1) == whoHasStar) {
cout << "*";
starOff = 5;
}
else {
cout << "";
starOff = 6;
}

cout << setw(starOff) << age << setw(18)
<< city << setw(18) << country << "\n";
}

void PersonInfo::ChangePersonData(string Name, int Age, string City, string Country) {
name = Name;
age = Age;
city = City;
country = Country;
}


If you wonder what whoHasStar is, it's a star printed after the name of the person, if that record has been edited.

So far so good, but the problem lies in my addRecord() function, the ability to add records to the end of the file.
Here's this code:

My addRecord() function


#include <iostream>
using namespace std;


#include <windows.h>
#include <string>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include "personInfo.h"


inline void eatline() { // I've never really understood what this does,
// and where in the code I need it, someone who knows?
while (cin.get() != '\n')
continue;
}


PersonInfo pInfo; // Temporary record keeper, the thing between reading and writing
const char *pFile = "personDB.dat"; // Main database file

fstream pfInOut; // File I/O-stream

int whoHasStar = 0; // Record number that has the star


////////////
// code
////////////


void addRecord() { // Adds one or more posts to the end of file
string Name, City, Country;
int Age;
char _Name[20], _City[20], _Country[20]; // This is because cin.get() won't work with strings! Any other workaround?


int ct = 0; // Record counter


pfInOut.open(pFile, ios_base::in | ios_base::ate | ios_base:: out | ios_base::app | ios_base::binary); // Is this the correct way of opening the file? Is ios_base::ate necessary?


if (pfInOut.is_open()) {
pfInOut.seekg(0);

cout << "\nThis is the current contents of the file \"" << pFile << "\":\n\n";
cout << "Rec #" << setw(18) << "Name" << setw(6) << "Age"
<< setw(18) << "City" << setw(18) << "Country" << "\n\n";

while (pfInOut.read((char *) &pInfo, sizeof pInfo)) { // Loops through the file, reads a record, and displays it, then continues to the next one
pInfo.DisplayDatabase(ct); // Should I use sizeof pInfo or sizeof PersonInfo?
ct++;
}
if (pfInOut.eof())
pfInOut.clear();
else {
cerr << "Error while reading file \"" << pFile << "\".\n";
exit(1);
}
}

else {
cerr << "Couldn't open \"" << pFile << "\".\n";
exit(2);
}

if (pfInOut.eof())
pfInOut.clear();


cout << "\nEnter the name of the person: ";
eatline(); // Is this where I should put eatline()?
cin.get(_Name, 20);
//eatline(); // ... or should I put it here...
//while (_Name[0] != '\0') { // This is a problematic area, my app seems to be skipping this loop, so I've removed this while loop, why is it skipping it?
//eatline(); // ... or here?
cout << "Enter the age of the person: ";
cin >> Age;
eatline(); // Needed?
cout << "Enter the name of the new city: ";
cin.get(_City, 20);
eatline(); // Needed?
cout << "Enter the country: ";
cin.get(_Country, 20);
eatline(); // Needed?


Name = _Name; // Okidoki, defining char[] info to a string...
City = _City; // And here...
Country = _Country; // ... and here


pInfo.ChangePersonData(_Name, Age, _City, _Country);


pfInOut.write((char *) &pInfo, sizeof pInfo) << flush; // Writing the record to the end of file
if (pfInOut.fail()) {
cerr << "Error while attempt to write - bye.\n";
exit(5);
}

whoHasStar = ct + 1;

pfInOut.close();


viewChangedDatabase();

//}
}

It will display the records incorrectly, only showing the last one in a proper way.
Here is a screen of how it looks like:

http://gabid001.thg.se/wrong.bmp


So there u have it, anyone who might know the solutions to the various problems here?

Help really appreciated, it means a lot to me to be able to finish this application.

Thanx in advance, guys!

/silkfire
Similar Threads
Reputation Points: 10
Solved Threads: 0
Newbie Poster
silkfire is offline Offline
8 posts
since May 2005
May 20th, 2005
0

Re: Need help with my console database app, program reading or writing incorrectly

Your biggest problem is trying to use stream.read() and stream.write() with a non-POD type. Because the string class is not a trivial class, and your PersonInfo struct has at least one of them, read and write are only guaranteed to cause undefined behavior. You would be better off defining a function that extracts and inserts fields from/to the database manually. Using unformatted binary I/O is tricky to get right and has a lot of restrictions in C++.
Reputation Points: 35
Solved Threads: 3
Posting Whiz in Training
Dogtree is offline Offline
232 posts
since May 2005
May 21st, 2005
0

Re: Need help with my console database app, program reading or writing incorrectly

Okay... so how should I do it with chars? I have problems with how I should create my function that takes char arrars (char[X]) as parameters...
Reputation Points: 10
Solved Threads: 0
Newbie Poster
silkfire is offline Offline
8 posts
since May 2005

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: Using data i read from *.* files
Next Thread in C++ Forum Timeline: help





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC