User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the C++ section within the Software Development category of DaniWeb, a massive community of 428,438 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 3,909 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our C++ advertiser: Programming Forums
Views: 1717 | Replies: 2
Reply
Join Date: May 2005
Posts: 8
Reputation: silkfire is an unknown quantity at this point 
Rep Power: 0
Solved Threads: 0
silkfire's Avatar
silkfire silkfire is offline Offline
Newbie Poster

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

  #1  
May 20th, 2005
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
AddThis Social Bookmark Button
Reply With Quote  
Join Date: May 2005
Posts: 232
Reputation: Dogtree is an unknown quantity at this point 
Rep Power: 4
Solved Threads: 2
Dogtree's Avatar
Dogtree Dogtree is offline Offline
Posting Whiz in Training

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

  #2  
May 20th, 2005
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++.
Reply With Quote  
Join Date: May 2005
Posts: 8
Reputation: silkfire is an unknown quantity at this point 
Rep Power: 0
Solved Threads: 0
silkfire's Avatar
silkfire silkfire is offline Offline
Newbie Poster

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

  #3  
May 21st, 2005
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...
Reply With Quote  
Reply

Only community members can participate in forum threads. You must register or log in to contribute.

DaniWeb C++ Marketplace
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 

Thread Tools Display Modes

Similar Threads
Other Threads in the C++ Forum

All times are GMT -4. The time now is 8:20 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC