質問

私は航空券予約ソフトウェアを作成していますが、Visual C++ についてはあまり知りません。簡易コンパイラ「TCWIN45」を使用しています。私のプログラムではファイル処理を使用したいのですが、すべての入力をテキスト ファイルに保存することに成功しました。検索オプションと変更オプションを追加する必要があります。ユーザーが検索を選択して名前を入力した場合、特定の行数にアクセスするにはどうすればよいですか。私のファイルには複数の乗客の記録が含まれていますが、唯一の乗客のデータを表示したいからです。修正の場合も同様です。特定の場所や行にアクセスし、上書きしたい。最も簡単な方法を教えてください。

これは、すべてのレコードを 1 つのテキスト ファイルに保存するコードです。

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------------------------------";
役に立ちましたか?

解決

Ali、これは、データベースを本当に使用したくない場合は、フラットファイルで実行できます。トリックは、次のいずれかです。1。)すべてのレコードを同じサイズまたは2.)ハードディスクからのレコードを非正規化できるように「十分な」情報を提供する「レコードヘッダー」を持っています。さまざまな種類のレコードを保存する場合、「十分な」情報は、RTTIの目的でレコードのサイズまたはレコードタイプになる可能性があります。レコードのオフセット用にインデックステーブルを保存できるように、各レコードのIDを保存することも便利です。

レコードにさまざまなサイズがある場合、レコードのシリアル化関数はこれを処理できる必要があります。実際、これを行うのは些細なことです。

インデックステーブルは、ファイルオフセットのテーブルです。

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;

したがって、レコードの位置を見つけるために、ファイルへのオフセット、つまりインデックス[Record_ID]を見つけます。レコードを追加することは、リンクリストにノードを追加するようなものですが、ノードはファイルにあります。レコードの削除は少し難しいです。 「Lazy Delete」を使用してレコードを削除する必要があり、後でこれらの削除されたレコードが再利用されます。ファイルから削除されたすべてのレコードを削除して、未使用のスペースを解放するシュリンク関数を書くこともできます。

この手法の制限は、レコードIDでのみ検索できることです。他の情報がある場合は、これをサポートするために追加のデータ構造を生成する必要があります。

あなたが実用的な例を望むならば、私はCでこれを行うコードを利用できます。ただし、これをゼロから行うことは実現可能ですが、努力する価値はありません。 SQLiteやMySQLなどのデータベースを使用するだけです。時間を節約できます。

例コード

他のヒント

コメントから他の回答まで、これを行うための最良の方法は、データをテキストファイルにまったく保存することではないようです。あなたはおそらく欲しいでしょう Reservation 予約のすべての情報を含むクラス。次に、何らかのコレクションを使用して、すべての予約を保存します。テキストファイルに書き込むと、膨大な量の不必要な難易度が追加されます。

このようなもの:

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

クラスメンバーごとに個別のクラスを作成した場合はさらに良いでしょう( Day クラス、a FlightType クラスなど)。

その後、ある種の使用を行います Map 特定の予約にアクセスしてメンバーを変更します。

おそらく、 reservation 単一の予約を表すクラスと、 data すべてのデータを保持するクラス vectorreservations.データ クラスには、 std::ostream 参照によって予約をテキスト ファイルに保存します (1 行に 1 つの変数を使用するのが最も簡単です)。また、を受け取るメンバー関数も必要になります。 std::istream 参照によってテキスト ファイルからデータを読み込みます。

プログラムの主要部分は (ここでは大量の仮定を立てていますが) ファイルを data とのクラス std::istream メンバー関数を使用し、ユーザーに何らかの ID を要求します。次に、次のメンバー関数を呼び出します。 data すべての要素をチェックします data■ 一致する ID が (参照により) 見つかるまでベクトルを実行し、ユーザーが一部のメンバーを変更できるようにします。次に、それは std::ostream メンバー関数を再度実行して変更を保存します。

ストリームは次のように処理されます。このサンプルでは、 data この質問は宿題のように見えますが、これはファイル処理の難しい部分を示しています。

#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;       
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top