我目前正在学习c++编程。我正在通过我在网上找到的一个编程项目,并尝试逐行重新创建它,寻找为什么某些事情的工作方式。这个项目是一个简单的酒店预订系统,它有一个菜单系统,并保存用户的输入,如姓名,地址,电话号码等。
我一直在寻找关于试图了解这段代码的某些部分。我想把用户的输入和保存到一个.dat文件,但它似乎并没有工作,我不知道为什么。有没有更好的方法来读写文本文件。
这是处理检查房间是否空闲或保留的函数。
#include <fstream>
#include "Hotel.h"
int Hotel::check_availabilty(int room_type){
int flag = 0;
std::ifstream room_check("Room_Bookings.dat",std::ios::in);
while(!room_check.eof()){
room_check.read((char*)this, sizeof(Hotel));
//if room is already taken
if(room_no == room_type){
flag = 1;
break;
}
}
room_check.close();//close the ifstream
return(flag);//return result
}
这是预订房间的代码
#include "Hotel.h"
#include "check_availability.cpp"
void Hotel::book_a_room()
{
system("CLS");//this clears the screen
int flag;
int room_type;
std::ofstream room_Booking("Room_Bookings.dat");
std::cout << "\t\t" << "***********************" << "\n";
std::cout << "\t\t " << "THE GREATEST HOTEL" << "\n";
std::cout << "\t\t" << "***********************" << "\n";
std::cout << "\t\t " <<"Type of Rooms "<< "\t\t Room Number" "\n";
std::cout << "\t\t" << " Standard" << "\t\t 1 - 30" "\n";
std::cout << "\t\t" << " Luxury" << "\t\t\t 31 - 45" "\n";
std::cout << "\t\t" << " Royal" << "\t\t\t 46 - 50" "\n";
std::cout << "Please enter room number: ";
std::cin >> room_type;
flag = check_availabilty(room_type);
if(flag){
std::cout << "\n Sorry, that room isn't available";
}
else{
room_no = room_type;
std::cout<<" Name: ";
std::cin>>name;
std::cout<<" Address: ";
std::cin>>address;
std::cout<<" Phone No: ";
std::cin>>phone;
room_Booking.write((char*)this,sizeof(Hotel));
std::cout << "Your room is booked!\n";
}
std::cout << "Press any key to continue...";
getch();
room_Booking.close();
}
这是Hotel.h文件
class Hotel
{
int room_no;
char name[30];
char address[50];
char phone[10];
public:
void main_menu();
void book_a_room();
int check_availabilty(int);
void display_details();
};
我不完全理解这部分while循环的作用。
room_check.read((char*)this, sizeof(Hotel));
如果你需要更多的信息,请问.任何提示和技巧,使这个更好的将受到欢迎。
Hotel
是一个完全自足的类型,没有堆分配或对外部对象的引用。 因此,我们可以通过简单地写出对象在内存中的表示来序列化它的状态,并通过做相反的事情来反序列化。
room_check.read((char*)this, sizeof(Hotel));
这行代码要求 room_check
输入流读取 sizeof(Hotel)
字节,并将其直接存储在 Hotel
所指向的对象 this
的生命。 实际上,你是将内存内容恢复到写入磁盘之前的状态。
(注意 (char*)this
最好写成 reinterpret_cast<char *>(this)
在C++中。)
这就是这个操作的反面。
room_Booking.write((char*)this,sizeof(Hotel));
用这种方式序列化而不是创建自己的数据结构有一些优势.
但是,也有一些缺点。
.dat
文件,当你去读取 "字符串"(字符数组)成员时,只要不对这些数组中的任何一个数组进行NUL终结,就会导致越界读取。使用不同的序列化机制,如利用JSON、XML、协议缓冲区等,需要更多的工作,但结果更可移植,因为你在磁盘上的数据结构不再与对象在内存中的布局挂钩。
当进行
room_check.read((char*)this, sizeof(Hotel));
你从流中读取数据,并写入缓冲区,但你需要指定必须读取多少字符...
room_check
包含的数据是一个流。room_check.read((char*)this, sizeof(Hotel));
从流中读取数据,并将其存储在当前实例的 Hotel
(this
). sizeof(Hotel)
告诉函数应该从流中读取多少字节。
room_check
包含类的数据 Hotel
在类声明中按顺序排列。
int room_no;
char name[30];
char address[50];
char phone[10];
有了这个声明,一个酒店实例的字节大小是已知的。sizeof(1*int + 30*char + 50*char + 10*char)
. 数据文件的内容被存储在当前的这个 Hotel
.