smpoojary
asked on
write problem in ios::in | ios:out | ios::app mode
hi all,
My code is like this (read, update, append bank account)
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
fstream data;
char temp[100];
data.open("d:\\database.tx t",ios::in | ios::out | ios::app | ios:: binary);
if(!data.is_open()) return 0;
data.read(temp,10); //test last account no.
strcpy(temp,"mahesh");
data.seekp(0,ios::end);
data.write(temp,10);
data.close();
return 0;
}
starting, the file database.txt is empty. This file is compressed code of my project.
The data I have written "mahesh" is not writing to database.txt file.
Please any body can help me out.
-Mahesh
My code is like this (read, update, append bank account)
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
fstream data;
char temp[100];
data.open("d:\\database.tx
if(!data.is_open()) return 0;
data.read(temp,10); //test last account no.
strcpy(temp,"mahesh");
data.seekp(0,ios::end);
data.write(temp,10);
data.close();
return 0;
}
starting, the file database.txt is empty. This file is compressed code of my project.
The data I have written "mahesh" is not writing to database.txt file.
Please any body can help me out.
-Mahesh
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
One doubt, Can you read and write to the file stream at the same time? Im a bit apprehensive of the same. Pls do check it out. Even if that both are possible, why are you opening in the 'append' mode. I believe 'ios::app|ios::binary' will be enough...
Mahesh, having checks like these would certainly help. After executing the program, i found that it was giving error for reading and writing to the file.
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
int main()
{
fstream data;
char temp[100];
data.open("d:\\database.tx t",ios::in | ios::out | ios::app | ios:: binary);
if(!data.is_open())
{
cout << "error opening file" << endl;
return 0;
}
data.read(temp,10); //test last account no.
if(data.fail())
{
cout <<"error reading from file" << endl;
}
strcpy(temp,"mahesh");
data.seekp(0,ios::end);
data.write(temp,10);
if(data.fail())
{
cout <<"error writing from file" << endl;
}
data.close();
return 0;
}
Mahesh, having checks like these would certainly help. After executing the program, i found that it was giving error for reading and writing to the file.
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
int main()
{
fstream data;
char temp[100];
data.open("d:\\database.tx
if(!data.is_open())
{
cout << "error opening file" << endl;
return 0;
}
data.read(temp,10); //test last account no.
if(data.fail())
{
cout <<"error reading from file" << endl;
}
strcpy(temp,"mahesh");
data.seekp(0,ios::end);
data.write(temp,10);
if(data.fail())
{
cout <<"error writing from file" << endl;
}
data.close();
return 0;
}
ASKER
hi all,
thanks for your replying.
Actually I am wiring multi-threaded programming(clients). This code is one part of that. All client threads are creating account, updating record and appending record at the same time. That's why I am using ios::in | ios::out | ios::app | ios::binary for read,update,append record same time using semaphore.
So, while starting, the file (database.txt) should be empty. For checking the last record I have to read the database(file). In this time, the file may be empty or not. If database is empty, the read statement gives empty string, isn't it? Then I have to make account_no to 1 and write to the database (writing first record).
I had modified my code, now you can understand my problem clearly.
#include <iostream>
#include <fstream>
using namespace std;
#define RECORD_SIZE 114
int main()
{
unsigned int unAcctNo;
double dBalance,dAmount;
string strName,strPhoneNo;
fstream data;
char Buff[RECORD_SIZE];
data.open("d:\\database.tx t",ios::in | ios::out | ios::app | ios:: binary);
if(!data.is_open())
{
cout << "Error: opening the file";
return 0;
}
strcpy(Buff,"\0");
data.seekg(0,ios::end);
data.read(Buff,RECORD_SIZE ); //Check the last record account no.
if(strcmp(Buff,"") == 0)
unAcctNo = 1;
else
{
sscanf(Buff,"%d %lf %s %s",&unAcctNo,&dBalance,st rName,strP honeNo);
unAcctNo = unAcctNo + 1;
}
strcpy(Buff,"\0");
dAmount = 54.65;
strName = "Mahesh";
strPhoneNo = "4523523454";
sprintf(Buff,"%d %lf %s %s\n",unAcctNo,dAmount,str Name.c_str (),strPhon eNo.c_str( ));
data.seekp(0,ios::end);
data.write(Buff,RECORD_SIZ E);
if(data.fail())
{
cout << "Error: while writing";
return 0;
}
data.close();
return 0;
}
Waiting for reply.
With warm regards
-Mahesh
thanks for your replying.
Actually I am wiring multi-threaded programming(clients). This code is one part of that. All client threads are creating account, updating record and appending record at the same time. That's why I am using ios::in | ios::out | ios::app | ios::binary for read,update,append record same time using semaphore.
So, while starting, the file (database.txt) should be empty. For checking the last record I have to read the database(file). In this time, the file may be empty or not. If database is empty, the read statement gives empty string, isn't it? Then I have to make account_no to 1 and write to the database (writing first record).
I had modified my code, now you can understand my problem clearly.
#include <iostream>
#include <fstream>
using namespace std;
#define RECORD_SIZE 114
int main()
{
unsigned int unAcctNo;
double dBalance,dAmount;
string strName,strPhoneNo;
fstream data;
char Buff[RECORD_SIZE];
data.open("d:\\database.tx
if(!data.is_open())
{
cout << "Error: opening the file";
return 0;
}
strcpy(Buff,"\0");
data.seekg(0,ios::end);
data.read(Buff,RECORD_SIZE
if(strcmp(Buff,"") == 0)
unAcctNo = 1;
else
{
sscanf(Buff,"%d %lf %s %s",&unAcctNo,&dBalance,st
unAcctNo = unAcctNo + 1;
}
strcpy(Buff,"\0");
dAmount = 54.65;
strName = "Mahesh";
strPhoneNo = "4523523454";
sprintf(Buff,"%d %lf %s %s\n",unAcctNo,dAmount,str
data.seekp(0,ios::end);
data.write(Buff,RECORD_SIZ
if(data.fail())
{
cout << "Error: while writing";
return 0;
}
data.close();
return 0;
}
Waiting for reply.
With warm regards
-Mahesh
Hi Mahesh,
If multiple threads are to be operating on this file, you must use thread synchronization so that only one thread does anything with the file at at time. fstreams are not inherently thread-safe.
If the program tries to read an empty file, you do not get an empty string. The stream goes to fail state and the input buffer is unchanged. In your case, you have an uninitialized character array, so after a failed read, it will contain garbage. You could initialize the array to an empty string, and then the following comparison would work, but it would be better to check the stream state, because if it is in the failed state, no other operations will work and the program will need to proceed accordingly.
--efn
If multiple threads are to be operating on this file, you must use thread synchronization so that only one thread does anything with the file at at time. fstreams are not inherently thread-safe.
If the program tries to read an empty file, you do not get an empty string. The stream goes to fail state and the input buffer is unchanged. In your case, you have an uninitialized character array, so after a failed read, it will contain garbage. You could initialize the array to an empty string, and then the following comparison would work, but it would be better to check the stream state, because if it is in the failed state, no other operations will work and the program will need to proceed accordingly.
--efn
ASKER
hi all,
I got the soluton.
After read the file, if read is failed, we have to clear the flags and write the data to the file. Like
memset(Buff,'\0',RECORD_SI ZE);
data.seekg(0,ios::beg);
data.read(Buff,RECORD_SIZE );
if(data.fail())
{
unAcctNo = 1;
data.clear(); // Clear the flags
}
else
{
sscanf(Buff,"%d %lf %s %s",&unAcctNo,&dBalance,st rName,strP honeNo);
unAcctNo = unAcctNo + 1;
}
memset(Buff,'\0',RECORD_SI ZE);
dAmount = 54.65;
strName = "Mahesh";
strPhoneNo = "4523523454";
sprintf(Buff,"%d %lf %s %s\n",unAcctNo,dAmount,str Name.c_str (),strPhon eNo.c_str( ));
data.seekp(0,ios::end);
data.write(Buff,RECORD_SIZ E);
if(data.fail())
{
cout << "Error: while writing";
return 0;
}
data.close();
Thanks for everybody
with warm regards
-Mahesh
I got the soluton.
After read the file, if read is failed, we have to clear the flags and write the data to the file. Like
memset(Buff,'\0',RECORD_SI
data.seekg(0,ios::beg);
data.read(Buff,RECORD_SIZE
if(data.fail())
{
unAcctNo = 1;
data.clear(); // Clear the flags
}
else
{
sscanf(Buff,"%d %lf %s %s",&unAcctNo,&dBalance,st
unAcctNo = unAcctNo + 1;
}
memset(Buff,'\0',RECORD_SI
dAmount = 54.65;
strName = "Mahesh";
strPhoneNo = "4523523454";
sprintf(Buff,"%d %lf %s %s\n",unAcctNo,dAmount,str
data.seekp(0,ios::end);
data.write(Buff,RECORD_SIZ
if(data.fail())
{
cout << "Error: while writing";
return 0;
}
data.close();
Thanks for everybody
with warm regards
-Mahesh
ASKER
hi all,
I want to know, how can I assign "Assisted Answer" and "Saturation answer". I know only put "Accepted answer".
-Mahesh
I want to know, how can I assign "Assisted Answer" and "Saturation answer". I know only put "Accepted answer".
-Mahesh
Ok, here are a few things to review in your code...
1. You don't need to seek to the end of the file to write as you have already opened it in append mode (MSDN - app, to seek to the end of a stream before each insertion).
2. Opening in 'app' mode assumes the file exists already. If it doesn't the open will fail. To test this try using 'trunc' mode that opens and truncates an existing file or creates a new one if no file exists. You could try your first form of open and if this fails try opening with 'trunc'. An exit error before 'return 0' would be useful.
3. If all else fails, try stepping through the code with the debugger!
Cheers,
EvilRix.