0

我有一个结构:

struct Ticket
{
    bool IsReserved; // Is the seat resereved (true)
    time_t SoldOn; //When has the ticket been bought
    double Price; // Price of the ticket
    Ticket() {  IsReserved = 0; Price = 0; SoldOn = 0; }
};

我已经根据需要在二进制文件中多次保存它,并且我正确读取了它。我的问题是,当用户想买票时,我什么时候才能只修改 1 个结构。例如,当他想购买第 5 个席位时,他应该转到第 5 个结构并仅更改该数据。这是我尝试做的方法。

std::cout<<"\nPlease enter how many tickets would you like to purchase : \n";
do
{   
    if(number<0 || number > freeSeats)
        std::cerr<<"Invalid input.try again: \n";
    std::cin>>number;

}while(number<0 || number > freeSeats);

int *t = new int[number];

for(int i = 0; i<number; i++)
{
    int seat = 0;

    do
    {

        std::cout<<"Please enter seat "<<i<<" : ";
        std::cin>>seat;

        file.clear();
        file.seekg(0,std::ios::beg);
        for(int i =1; i <= seat; i++)
        {
            serializeTickets(file,ticket);
        }
        if(ticket.IsReserved == 1)
            std::cout<<"The ticket has already been reserved\n";
    }while(ticket.IsReserved == 1);

    t[i] = seat;
}

file.close();

schedule.serializeTargetLine(choice);
std::ofstream myFile(ticketsFileName,std::ios::binary || std::ios::out);

for(int i = 0; i<number; i++)
{
    time_t timer(0);
    std::time(&timer);

    myFile.seekp(+(t[i] - 1)*sizeof(Ticket),std::ios::beg);

    ticket.IsReserved=1;
    ticket.Price = atof(schedule.getPrice().c_str());
    ticket.SoldOn = timer;

    myFile.write(reinterpret_cast<char*> (&ticket),sizeof(Ticket));
}

delete[] t;
myFile.close();
4

3 回答 3

0

写入文件时,我可能会在将结构数据写入文件之前使用以下内容。

#pragma pack(1)

之后,只需使用sizeof(ticket) * seat文件开头的查找偏移量即可。

file.seekg((sizeof(ticket) * seat), std::ios::beg);
于 2013-05-20T06:47:56.703 回答
0

如果您使用 GCC 进行编译,我鼓励您在编译器标志中添加 -Wall 以获得最大的编译器帮助。

问题似乎是您没有打开文件进行写入:

std::ofstream myFile(ticketsFileName,std::ios::binary || std::ios::out);

当你可能不是

std::ios::binary | std::ios::out

或 (std::ios::binary | std::ios::out)

如果您打开完整的编译器警告,它会告诉您您有一个布尔运算,您可能不希望有一个逻辑运算。

而且,是的,您可能应该在结构周围使用 pragma pack。请参阅http://msdn.microsoft.com/en-us/library/ms253935(v=vs.80).aspxhttps://stackoverflow.com/a/9852860/257645

请注意,除非您的目标是较旧的编译器,否则您可以这样做:

#pragma pack(push, 1)
struct ... {
    ...
};
#pragma pack(pop)

(简短版:这告诉编译器使用内存中的结构表示,该结构的运行时性能可能较低,但会为这样的存储创建较少依赖环境的占用空间)

于 2013-05-20T06:50:36.077 回答
0

这看起来可能是一个真正的数据库的工作,它已经为你想好了所有这些繁琐的细节(但当然还有其他的繁琐细节)。

也就是说,您的代码乍一看应该可以工作(除了 kfsone 指出的 | vs || 问题)。如果你允许我挑剔一点:

  • std::vector应该优先于 array-new,因为它封装了最容易出错的部分。
  • 从技术上讲,直接向/从fiie 传输Ticket结构是违反标准的,因为它有一个构造函数。
  • 您可能需要考虑使用std::fstreamopen 来读取和写入,而不是两次打开同一个文件。
  • 在读取和写入文件时,很多事情都可能出错。你的代码应该优雅地处理这些事情。例如,
    • 允许 read() 和 write() 读取/写入的字节数少于您指定的字节数
    • 如果查找超出文件末尾,它可能会失败。
于 2013-05-20T07:06:44.620 回答