?
Solved

write problem in ios::in | ios:out | ios::app mode

Posted on 2004-11-30
7
Medium Priority
?
4,292 Views
Last Modified: 2011-08-18
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
0
Comment
Question by:smpoojary
7 Comments
 
LVL 15

Accepted Solution

by:
efn earned 60 total points
ID: 12713124
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
 
LVL 40

Expert Comment

by:evilrix
ID: 12713263
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
 
LVL 1

Expert Comment

by:kopos
ID: 12713284
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 4

Author Comment

by:smpoojary
ID: 12713425
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
 
LVL 15

Expert Comment

by:efn
ID: 12713480
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
 
LVL 4

Author Comment

by:smpoojary
ID: 12780067
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
 
LVL 4

Author Comment

by:smpoojary
ID: 12780105
hi all,

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

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
Suggested Courses

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question