1

I am making an airline reservation software and I don't know much about the Visual C++. I am using the simple compiler "TCWIN45". In my program I wish to use file handling and I am succeed to save all the inputs in text file. i need to add search option and modification option. if user choose search and Enter the name then how can I access specific number of lines. because my files contains the record of multiple passengers but I want to show the only one's data. same is the case for modification. I want to access specific location or line and also to overwrite it. please suggest me the most simplest way.

This is my code to save all the record in one text file:

ofstream thefile("ID.txt" , ios::app);
thefile<<"\n\nDay : "<<p1[i].day<<"\nFlight Date : "<<p1[i].date<<"\nFlight Type : "<<p1[i].type<<"\nReturn Date : "<<p1[i].rdate<<"\nDeparture Place : "<<p1[i].from<<"\nDestination : "<<p1[i].to<<"\nClass Type : "<<p1[i].clas<<"\nTime of Flight : "<<p1[i].time<<"\nTitle : "<<p1[i].prefix<<"\nFirst Name : "<<p1[i].fname<<"\nLast Name : "<<p1[i].lname<<"\nDate of Birth : "<<p1[i].dob<<"\nPassport Number : "<<p1[i].ppt_no<<"\nExpiry Date : "<<p1[i].edate<<"\n Contact Number : "<<p1[i].cont<<"\nMeal Type : "<<p1[i].meal<<"\n\n------------------------------";
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Ali Hanif
  • 23
  • 4
  • Does your compiler have any line length limitations? – David Heffernan Sep 06 '11 at 18:57
  • 1
    With a text based file, random access is not going to give you appropriate results unless the entries are a known fixed length. You may need to simply read the file and look for appropriate sentinel values. – Chad Sep 06 '11 at 18:59
  • Is this a homework assignment? If so, it should be labeled as such – Mooing Duck Sep 06 '11 at 19:05
  • As I am writing "ID.txt" ofstream thefile("ID.txt" , ios::app); can I replace the specification "ID.txt" with some variable or string? which i have already declared. I just change the name of variable or string and a new file is automatically generates with that new name of string. is that possible?? – Ali Hanif Sep 06 '11 at 19:46
  • What else type I can use to save a file?? and how can i access specific number of lines for search and specific portion for modification – Ali Hanif Sep 06 '11 at 19:46
  • That code is completely illegible. And "TCWIN45" is Turbo C++ which is hardly "the simple compiler". It's outdated and half-broken. Switch to GCC to save yourself a headache. – Lightness Races in Orbit Sep 06 '11 at 23:01

3 Answers3

0

You'll probably want to define a reservation class that represents a single reservation, and a data class, that holds all your data, as a vector of reservations. The data class will want to have a member function that takes a std::ostream by reference, and saves the reservations to a text file, (easiest is one variable per line). It will also want a member function that takes a std::istream by reference and reads in the data from the text file.

The main part of your program would (I'm making TONS of assumptions here) load the file into the data class with the std::istream member function, and asks the user for some sort of ID. You then call a member function of data that checks all of the elements in datas vector until it finds the matching ID (by reference), and lets the user change some members. Then it calls the std::ostream member function again to save the changes.

Streams are handled like this. In this sample, I do not use the data class or a vector, since this question looks suspiciously like homework, but this shows the tricky parts of file handling.

#include <string>
#include <iostream>
#include <fstream>

class Reservation {
    std::string ID;
    std::string date;
public:
    //default constructor
    Reservation()
    {}
    //helpful constructor
    Reservation(std::string _id, std::string _date)
    :ID(_id), date(_date)
    {}
    //copy constructor
    Reservation(const Reservation& b)
    :ID(b.ID), date(b.date)
    {}
    //move constructor
    Reservation(Reservation&& b)
    :ID(std::move(b.ID)), date(std::move(b.date))
    {}
    //destructor
    ~Reservation() 
    {}
    //assignment operator
    Reservation& operator=(const Reservation& b)
    {
        ID = b.ID;
        date = b.date;
        return *this;
    }
    //move operator
    Reservation& operator=(Reservation&& b)
    {
        ID = std::move(b.ID);
        date = std::move(b.date);
        return *this;
    }
    //save
    std::ostream& save(std::ostream& file) {
        file << ID << '\n';
        file << date << '\n';
        return file; //be in the habit of returning file by reference
    }
    //load
    std::istream& load(std::istream& file) {
        std::getline(file, ID);
        std::getline(file, date);
        return file; //be in the habit of returning file by reference
    }
};

int main() {
    Reservation reserve; //create a Reservation to play with

    {  //load the reservation from loadfile
        std::ifstream loadfile("myfile.txt");
        reserve.load(loadfile);
    }

    //display the reservation
    reserve.save(cout);

    { //save the reservation to a different file
        std::ofstream savefile("myfile2.txt");
        reserve.save(savefile);
    }
    return 0;       
}
Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
  • As I am writing "ID.txt" ofstream thefile("ID.txt" , ios::app); can I replace the specification "ID.txt" with some variable or string? which i have already declared. I just change the name of variable or string and a new file is automatically generates with that new name of string. is that possible?? – Ali Hanif Sep 06 '11 at 19:41
  • yes, in your example "ID.txt" can be replaced with any `char*` variable or literal, and that file will be created and written to. In my demo code, I use `myfile2.txt`. – Mooing Duck Sep 06 '11 at 20:49
  • but your demo is of class type. can you do it in strcuture?? like i did struct twikid { char day[10]; int d; int m; int y; char from[15]; char to[15]; char time[20]; char clas[15]; char fname[15]; char lname[15]; char ppt_no[15]; char cont[15]; char meal[10]; char type[10]; int seat; long double adult; long double child; long double infant; char prefix[7]; int bd; int bm; int by; int ed; int em; int ey; char rdate[15]; long double price; char pnr[8]; char tkt[8]; long double tprice; long double tax; long double amount; }p1[20]; – Ali Hanif Sep 06 '11 at 20:57
  • Yes, anything a class can do, a structure can also do. The only difference is class members are private by default, and struct members are public by default. Did you try to see if it works before asking questions? – Mooing Duck Sep 06 '11 at 21:07
  • yes, my compiler is giving error on std, string, loadfile I am using turbo compiler. I have no practice on visual c++ yet. – Ali Hanif Sep 06 '11 at 21:19
0

From your comments to other answers, it does not seem like the best way for you to do this is to store the data in a text file at all. You will probably want a Reservation class that contains all of the information for the reservation. Then, use some kind of Collection to store all of the reservations. Writing to a text file just adds a huge amount of unnecessary difficulty.

Something like this:

class Reservation
{
    std::string day;
    std::string date;
    std::string flightType;
    std::string meal;
    /* ... */
};

It would be even better if you made separate classes for each one of the class members (like a Day class, a FlightType class, etc.).

You would then use some kind of Map to access a particular reservation and change its members.

Daniel
  • 6,595
  • 9
  • 38
  • 70
  • @Ali: Check out my addition to my answer. – Daniel Sep 06 '11 at 20:42
  • I used the structure but this kind of change in class or in structure is only on run time. but via file handling we can save that data permanently.. – Ali Hanif Sep 06 '11 at 20:46
  • struct twikid { char day[10]; int d; int m; int y; char from[15]; char to[15]; char time[20]; char clas[15]; char fname[15]; char lname[15]; char ppt_no[15]; char cont[15]; char meal[10]; char type[10]; int seat; long double adult; long double child; long double infant; char prefix[7]; int bd; int bm; int by; int ed; int em; int ey; char rdate[15]; long double price; char pnr[8]; char tkt[8]; long double tprice; long double tax; long double amount; }p1[20]; – Ali Hanif Sep 06 '11 at 20:50
  • @Ali: If you are worried about permanent storage, perhaps use some delimiter in your text file to separate entries. XML format is always an option. Unfortunately, you will still be stuck reading the entire file when you want to access a particular reservation (or at least the part of the file starting at the beginning and ending with the reservation that you are looking for). – Daniel Sep 06 '11 at 20:53
  • @Ali: Check [this](http://www.boost.org/doc/libs/1_47_0/libs/serialization/doc/index.html) out. – Daniel Sep 06 '11 at 20:57
  • yes, i only know how to write, read file from text file or a new function seekp(); is i learnt from here to get to the point but that will not enough. I am trying to auto create separate file for each user... – Ali Hanif Sep 06 '11 at 21:00
0

Ali, this can be done in a flat file if you really want to not use a database. The trick, is to either: 1.) have all records the same size OR 2.) have a "record header" that provides "enough" information to be able to unserialize the record from the hard disk. If you store different kinds of records, "enough" information could be size of the record or a record type for RTTI purposes. I find it useful to also store an ID for each record so that I can store an index table for record offsets.

If you records have varying sizes, then your record's serialization functions have to be able to handle this. In fact, it is trivial to do this.

The index table is a table of file offsets.

typedef uint16_t record_id;
typedef long offset_t;

offset_t  indices[ MAX_RECORDS ];


typedef struct _record {
     uint16_t type;
     uint16_t id;
     offset_t next;
     offset_t prev;
} record;

typedef struct _header {
   uint32_t count;
   offset_t first_record;
   offset_t deleted_record;
} header;

So to find the position of the record, you find the offset into the file, which is indices[ record_id ]. Adding a record is like adding a node to a linked list, but the nodes are in the file. Deleting records is a little tricky. You have to use "lazy delete" to delete records and later these deleted records get reused. You can even write a shrink function that will remove all deleted records from the file to free up unused space.

The limitations of this technique is that you can only search by record id. If you have other information, you will need to generate additional data structures to support this.

I have code available that does this in C if you would like a working example. However, doing this from scratch is feasible but NOT WORTH THE EFFORT. Just use a database like Sqlite or MySQL--it will save time!

Example Code

Man Vs Code
  • 1,058
  • 10
  • 14
  • how can i attach the database with my compiler?? – Ali Hanif Sep 06 '11 at 21:22
  • Alas, your compiler may be too old to be used with these modern tools. The flat file approach I outlined should work but will require some code to be written. – Man Vs Code Sep 06 '11 at 21:28
  • Are you allowed to use third party libraries? – Man Vs Code Sep 06 '11 at 21:33
  • [Check my code](http://codepad.org/5mwog7TM) and try to merge your code what you are saying.. please – Ali Hanif Sep 06 '11 at 21:46
  • I will help you out, once I get home from work. Try thinking about how you could use file offsets (like the ones returned from ftell()) to create a linked data structure in a file. If you are familiar with a linked list, then you could imagine how the next/prev pointers could be replaced with file offsets. – Man Vs Code Sep 06 '11 at 22:18
  • No I have no idea how to do it. please help me when you will be free. I ll wait for you.. thanks for your time.. – Ali Hanif Sep 06 '11 at 22:32
  • [link](http://www.manvscode.com/downloads/test-flat-db.c) test-flat-db.c [link](http://www.manvscode.com/downloads/flat-db.c) flat-db.c [link](http://www.manvscode.com/downloads/flat-db.h) test-flat-db.h Use my code as an example. It doesn't have to be as complex as mine. My approach assumes all records have a consistent size (see #1). I have written others that use the serialization approach (see #2). You will need to port it to Turbo C. Maybe you can do that as an exercise. – Man Vs Code Sep 06 '11 at 22:42