我正在制作航空公司预订软件,我对Visual C ++知之甚少。我使用简单的编译器“TCWIN45”。在我的程序中,我希望使用文件处理,并成功保存文本文件中的所有输入。我需要添加搜索选项和修改选项。如果用户选择搜索并输入名称,那么我该如何访问特定的行数。因为我的文件包含多名乘客的记录,但我想显示唯一的数据。同样是修改的情况。我想访问特定的位置或线路,也要覆盖它。请建议我最简单的方法。
这是我将所有记录保存在一个文本文件中的代码:
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------------------------------";
答案 0 :(得分:0)
您可能希望定义代表单个预订的reservation
类,以及保存所有数据的data
类,vector
reservation
}秒。数据类将希望有一个成员函数,它通过引用获取std::ostream
,并将预留保存到文本文件中(最简单的是每行一个变量)。它还需要一个成员函数,它通过引用获取std::istream
并从文本文件中读取数据。
你的程序的主要部分(我在这里做了一些假设)将文件加载到data
成员函数的std::istream
类中,并询问用户某种ID 。然后,您调用data
的成员函数,该函数检查data
向量中的所有元素,直到找到匹配的ID(通过引用),并让用户更改某些成员。然后它再次调用std::ostream
成员函数来保存更改。
Streams是这样处理的。在这个示例中,我不使用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;
}
答案 1 :(得分:0)
从您的评论到其他答案,您似乎最好的方法是将数据存储在文本文件中。您可能需要一个Reservation
类,其中包含预订的所有信息。然后,使用某种Collection来存储所有预订。写入文本文件只会增加大量不必要的困难。
这样的事情:
class Reservation
{
std::string day;
std::string date;
std::string flightType;
std::string meal;
/* ... */
};
如果为每个类成员(例如Day
类,FlightType
类等)创建单独的类,那会更好。
然后,您可以使用某种Map
来访问特定的预订并更改其成员。
答案 2 :(得分:0)
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;
因此,要找到记录的位置,您会在文件中找到偏移量,即index [record_id]。添加记录就像将节点添加到链接列表,但节点位于文件中。 删除记录有点棘手。您必须使用“延迟删除”来删除记录,稍后这些已删除的记录将被重用。您甚至可以编写一个收缩功能,它将从文件中删除所有已删除的记录,以释放未使用的空间。
此技术的局限性在于您只能按记录ID进行搜索。如果您有其他信息,则需要生成其他数据结构以支持此功能。
如果您想要一个有效的示例,我有可用的代码在C中执行此操作。但是,从头开始这样做是可行的,但并非值得努力。只需使用像Sqlite或MySQL这样的数据库 - 它将节省时间!
示例代码