在二进制文件中编写时如何跳过结构[c ++]

时间:2013-05-20 06:29:31

标签: c++ file binary structure ofstream

我有一个结构:

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();

3 个答案:

答案 0 :(得分:0)

在编写文件时,我可能会在将struct data写入文件之前使用以下内容。

#pragma pack(1)

之后,只需使用sizeof(ticket) * seat作为文件开头的搜索偏移量。

file.seekg((sizeof(ticket) * seat), std::ios::beg);

答案 1 :(得分: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)

如果你打开完整的编译器警告,它会告诉你你有一个布尔运算,你可能意味着没有逻辑。

,是的,你可能should use pragma pack around the structure。请参阅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)

(简短版本:这告诉编译器使用结构的内存中表示,这可能会降低运行时性能,但会为这样的存储创建一个与环境无关的足迹)

答案 2 :(得分:0)

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

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

  • std::vector应优先于array-new,因为它封装了容易出错的部分。
  • Ticket结构直接嵌入到文件中是从技术上违反标准,因为它有一个构造函数。
  • 您可能需要考虑使用std::fstream打开以进行读取和写入,而不是两次打开相同的文件。
  • 阅读和编写文件时,很多事情都可能出错。您的代码应该优雅地处理这些事情。例如,
    • 允许read()和write()读取/写入比指定的字节少的字节
    • 如果搜索超过文件的末尾,则可能会失败。