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
LVL 4
smpoojaryAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

efnCommented:
I suggest you add some checks and outputs so that you can see what is going on.  For example, if the open fails, put out a message before exiting.  If the file is empty, the read will fail, the stream will go into a failed state, and nothing else will work.  You could add some statements to check the state of the stream by calling data.fail().  For example,

if (data.fail())
  cout << "Read failed";

You can check the stream state after the seekp and write calls as well as the read call.

--efn
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
evilrixSenior Software Engineer (Avast)Commented:
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.

0
koposCommented:
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;
}
0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

smpoojaryAuthor Commented:
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
0
efnCommented:
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
0
smpoojaryAuthor Commented:
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
0
smpoojaryAuthor Commented:
hi all,

   I want to know, how can I assign "Assisted Answer" and "Saturation answer". I know only put "Accepted answer".
   -Mahesh
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.