Hi everyone, I am trying to record some information in a file and allow user to delete a record. I am facing this message in Autos section of MVS (Error reading character of string). Here is the code:
int removeRecord(string name, int &row) //remove a record
{
const string data="database.txt";
fstream records;
records.open(data.c_str());
const string cpData="temp.txt";
fstream temp;
temp.open(data.c_str());
string firstname, secondname,age,tem;
if (records.is_open() &&temp.is_open()){
while(records>>firstname>>secondname>>age)
{
if(firstname!=name){
temp<<firstname<<' ' <<secondname<<' '<<age<<endl;
}
}cout<<"\nis no deleted!\n";
records.close();
temp.close();
records.open("database.txt");
temp.open("temp.txt");
while(records>>firstname>>secondname>>age)
{
temp << records;
}
records.close();
temp.close();
row--;
cout<<row;
}
else cout<<"\nError oppening file\n";
return row;
}
If I delete the any row (except last roe) it works but then add a copy of last record (sometimes fully sometimes partially) at the end of the file!!
if i delete the last record it does not do anything.
Both temp and records refer to the same file in the first loop, which I don't think it's likely you meant to do. records is guaranteed to be in an error state from line 18 onward and that is never cleared.
It isn't clear what "row" is supposed to represent. It kind of looks like you mean it to represent the number of rows in the file. I'm not sure why you would need to feed it to the function that is reading the file. I'm equally unsure why it's passed in by reference, modified and returned by the function.
The following does, I think, what you intended to do, but I got rid of the row parameter and returned the number of records that are removed. (Do you really want to specify records to remove with a first name only?)
unsigned removeRecord(string name) //remove a record
{
const string data="database.txt";
const string cpData="temp.txt";
unsigned recordsRemoved = 0 ;
{ // limit the scope of records and temp.
ifstream records( data.c_str() ) ;
ofstream temp( cpData.c_str() ) ;
if ( !records || !temp )
{
cout << "Error opening file\n" ;
return recordsRemoved ;
}
string first, second, age ;
while ( records >> first >> second >> age )
{
if ( first == name )
++recordsRemoved ;
else
temp << first << ' ' << second << ' ' << age << '\n' ;
}
}
if ( recordsRemoved )
{
cout << recordsRemoved << " records removed.\n" ;
// at this point one would delete the file named database.txt and rename
// the file named temp.txt to database.txt. Or, we can do the following, which
// seems to be what you were attempting to do:
ifstream temp(cpData.c_str()) ;
if ( !temp )
{
cerr << "Unable to complete removal(s).\n" ;
return recordsRemoved ;
}
ofstream records(data.c_str()) ;
// TODO: error check here.
string first, second, age ;
while ( temp >> first >> second >> age )
records << first << ' ' << second << ' ' << age << '\n' ;
}
else
cout << name << " wasn't found in the database.\n" ;
return recordsRemoved ;
}