"BobR" <Re***********@worldnet.att.netwrote in message
news:TN*********************@bgtnsc04-news.ops.worldnet.att.net...
>
B. Williams wrote in message ...
>>
"B. Williams" <wi*******@hotmail.comwrote in message...
>>>I need some assistance with random access file processing. I have a
function that I would like to change from sequential file processing to
random access. Thanks in advance.
void updatePower(string filename) {
ifstream in(filename.c_str(), ios::in);
int cnt = 0;
// read all records into database until we reach the end of the file
while (!in.eof()) {
database[cnt++].input(in);
}
in.close();
int id;
cout << "Enter entry ID to change balance:"; //for this using the
//
overloaded
>> cin >id;
// check array bounds for databse, 0 to 49
if (id<0 || id>49) {
cout << "illegal ID - abort." << endl;
return;
}
// enter new power
double power;
cout << "Enter new power:";
cin >power;
// set new customer balance
database[id].setupdatePower(power);
// write customers back to text file
ofstream ofs(filename.c_str(), ios::out);
for (int i=0;i<cnt-1;i++)
database[i].output(ofs);
ofs.close();
}
Do I need to provide more information?
Ahh, finally a question!! Yes, you need to tell *exactly* what you want to
do, what the code you showed is doing and what it is not doing (that you
expect).
There are many posts in this NGs archive that show why 'while(x.eof())'
often
produces an extra loop.
You also failed to show what 'database' is.
I'd forget about 'random file access', and work out of memory (assuming
the
whole file will fit).
std::vector<std::stringdata;
void updatePower( string filename ){
ifstream in( filename.c_str() );
if(!in){ throw "ERROR: Open ";} // or something
for( std::string line; std::getline( in, line ); ){
data.push_back( line );
}
in.close();
// --- use 'data' ---
// --- change 'data' ---
// --- write 'data' back to file ---
ofstream ofs( filename.c_str() );
if( not ofs ){ throw "ERROR: Write ";} // or something
for( size_t i(0); i < data.size(); ++i ){
ofs<<data[ i ]<<std::endl;
}
ofs.close();
return;
} // updatePower(string)
Reading a chunk from the middle of a file is fairly easy if you know
exactly
where the chunk is. Writeing a chunk in the middle of a file is where
everything goes south for the winter. (It depends on the file system used
(there are hundreds), and C++ does not address 'file system specific'
things.
(..and needs a std lib to even know that there is a file system! <G>))
You could set the write point using 'seekp' (std::ios_base::ate). But,
when
you write to that spot, the rest of the file would be truncated, so, you'd
need to copy the rest of the file to that point. (loosely speaking)
The easier way in C++ is to read file, modify, write file.
--
Bob R
POVrookie
Bob,
I'll post the entire program. I wrote this code to process files, but now I
need to modify it for random access file processing.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::ios;
using std::cerr;
using std::ostream;
using std::istream;
#include <cstring>
#include <fstream>
using std::ofstream;
using std::ifstream;
#include <string>
using std::string;
class PPG{
public:
PPG(char *a, char b, int c)
{ dresscolor =b;
power = c;
setname(a);}//end constructor 1
PPG()
{ setname("Ms.Bellum");
dresscolor ='p';
power = 0;
}//end default constructor
char *getname()const {return name;}
void setname(char *a){
int l =strlen(a);
name = new char[l+1];
strcpy(name,a);
name[l] = '\0';
}//end setname
void output(ostream & out) {
out << name << ' ' << dresscolor << ' ' << power << endl;
}
void input(istream &in) {
in >name >dresscolor >power;
}
void setupdatePower(double p) { power = p; }
int getpower() const{return power;}
void setpower(int z){power = z;}
char getdresscolor() const{return dresscolor;}
void setdresscolor(char v){dresscolor=v;}
void print() const
{
ofstream outGirlsFile( "girls.txt", ios::app); //if I change this to in
if (!outGirlsFile)//instead of app then my file won't have any repeat
{
cerr << "File could not be opened" << endl;
exit(1);
}
outGirlsFile <<name << " " << dresscolor << " " << power << "\n";
cout <<name << " likes to wear ";
switch (dresscolor){
case 'g': case 'G':
cout <<"green dresses. She uses her ";break;
case 'b':case 'B':
cout <<"blue dresses. She uses her ";break;
case 'p': case 'P':
cout <<"pink dresses. She uses her ";
}//end switch
if (power == 1)
{
cout << "ice breath to defeat her enemies.\n";
}
else if (power ==2)
{
cout << "ability to talk to squirrels to confuse evil villians.\n";
}
else if (power ==3)
{
cout <<"bad attitude to stop evil doers.\n";
}
else
cout <<"girl power to rule the world.\n";
}//end print
bool operator==(PPG &ppg)
{ return (strcmp(name, ppg.name)==0); }
private:
char * name;
char dresscolor; //g-reen, b-lue, p-pink
int power; //1-ice breath, 2- squirrel speak, 3-bad attitude
}; //end class
void outputLine( char *, char, int);
PPG database[50];
// list all entry records already store in our file
void ListAllRecords(string filename) {
ifstream in(filename.c_str(), ios::in); // create input stream to file
PPG p; // use entry object to hold data
int count=0; // keep track of how many entries
// are in the file
// test to see if file exists, if not 'in.is_open()'returns false
if (!in.is_open()) {
cout << "No Records to display." << endl;
return;
}
// read each entry and store in our array of entries called 'database'
while (!in.eof())
database[count++].input(in);
in.close();
// display entries to the screen by sending cout to the ppg::output
function
for (int i=0;i<count-1;i++) {
cout << i << ") ";
database[i].output(cout);
}
}
void updatePower(string filename) {
// open text file for reading
ifstream in(filename.c_str(), ios::in);
int cnt = 0;
// read all records into database until we reach the end of the file
while (!in.eof()) {
database[cnt++].input(in);
}
// close text file
in.close();
int id;
cout << "Enter entry ID to change balance:";
cin >id;
if (id<0 || id>49) {
cout << "illegal ID - abort." << endl;
return;
}
// enter new power
double power;
cout << "Enter new power:";
cin >power;
// set new customer balance
database[id].setupdatePower(power);
// write customers back to text file
ofstream ofs(filename.c_str(), ios::out);
for (int i=0;i<cnt-1;i++)
database[i].output(ofs);
ofs.close();
}
main.cpp
#include "ppg.h" //note iostream is included in ppg.h so it is indirectly
included here
#include <string>
using std::string;
int main()
{
PPG p1; //here's a call to our default constructor
p1.print();
PPG girl1("Bubbles", 'b', 2);
girl1.print();
PPG badgirl("Princess",'g', 4);
badgirl.print();
cout << endl;
cout << "1) list all records from file girls.txt " << endl;
cout << "2) change the power for a name" << endl;
cout << "3) Quit." << endl;
cout << endl;
int choice=0;
string filename="girls.txt"; // name of our text file
while (choice!=3) {
cout << "Enter choise(1-3):";
cin >choice;
switch(choice) {
case 1:
ListAllRecords(filename);
break;
case 2:
updatePower(filename);
break;
}
}
return 0;
}//end main