Link to home
Start Free TrialLog in
Avatar of smpoojary
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.txt",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
ASKER CERTIFIED SOLUTION
Avatar of efn
efn

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of evilrix
Hi,

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.

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.txt",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;
}
Avatar of smpoojary
smpoojary

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.txt",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,strName,strPhoneNo);
            unAcctNo = unAcctNo + 1;
      }

      strcpy(Buff,"\0");
      dAmount = 54.65;
      strName = "Mahesh";
      strPhoneNo = "4523523454";
      sprintf(Buff,"%d %lf %s %s\n",unAcctNo,dAmount,strName.c_str(),strPhoneNo.c_str());

      data.seekp(0,ios::end);
      data.write(Buff,RECORD_SIZE);
      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
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_SIZE);
      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,strName,strPhoneNo);
            unAcctNo = unAcctNo + 1;
      }

      memset(Buff,'\0',RECORD_SIZE);
      dAmount = 54.65;
      strName = "Mahesh";
      strPhoneNo = "4523523454";
      sprintf(Buff,"%d %lf %s %s\n",unAcctNo,dAmount,strName.c_str(),strPhoneNo.c_str());

      data.seekp(0,ios::end);
      data.write(Buff,RECORD_SIZE);
      if(data.fail())
      {
            cout << "Error: while writing";
            return 0;
      }
      data.close();

    Thanks for everybody
    with warm regards
    -Mahesh
hi all,

   I want to know, how can I assign "Assisted Answer" and "Saturation answer". I know only put "Accepted answer".
   -Mahesh