如何编辑二进制文件中的特定值

How to edit specific value in binary file?

本文关键字:二进制文件 何编辑 编辑      更新时间:2023-10-16

我有一个飞行结构,它正在写入二进制文件,我想编辑航班目的地,但我不知道该怎么做。这是我用于获取用户输入和写入二进制文件的代码。

struct Flight_Details {
    char destination[99];
    char departure[99];
    char time_depart[80];
    char time_arrive[80];
    int flight_number;
};
switch (menu)
        {
            case MENU::NEW_FLIGHT: {
                Flight_Details flight_d;
                cout << "Enter Departure: ";
                cin >> flight_d.destination;
                cout << "Enter Destination: ";
                cin >> flight_d.departure;
                cout << "Enter Departure Time: ";
                cin >> flight_d.time_depart;
                cout << "Please enter arriving time: ";
                cin >> flight_d.time_arrive;
                cout << "Flight Number: ";
                cin >> flight_d.flight_number;
                ofstream file;
                file.open("Flgiht_Details.data", ios::binary);
                if (!file) cout << "Could create/open file";
                else {
                    file.write((char*)&flight_d, sizeof(flight_d));
                    file.close();
                }
                break;
            }
            case MENU::OUTPUT_FILE: {
                ifstream readFile;
                readFile.open("Flgiht_Details.data");
                if (!readFile) cout << "Couldn't open file";
                else {
                    readFile.seekg(0, ios::end);
                    int fileSize = readFile.tellg();
                    int countOfFlights = fileSize / sizeof(Flight_Details);
                    readFile.seekg(0, ios::beg);
                    Flight_Details* flight = new Flight_Details[countOfFlights];
                    readFile.read((char*)flight, countOfFlights *sizeof(Flight_Details));
                    readFile.close();
                    for (int i = 0; i < countOfFlights; i++)
                    {
                        cout << flight[i].destination << "n" << flight[i].departure << "n" << flight[i].time_depart << "n" << flight[i].time_arrive << "n" << flight[i].flight_number << "nn";
                    }
                    break;
                }
            }
            case MENU::EDIT: {
                Flight_Details* flight_d;
                ifstream readFile;
                readFile.open("Flgiht_Details.data");
                if (!readFile) cout << "Couldn't open file";
                else {
                    readFile.seekg(0, ios::end);
                    int fileSize = readFile.tellg();
                    int countOfFlights = fileSize / sizeof(Flight_Details);
                    readFile.seekg(0, ios::beg);
                    Flight_Details* flight = new Flight_Details[countOfFlights];
                    readFile.read((char*)flight, countOfFlights * sizeof(Flight_Details));
                    readFile.close();
                    ofstream file;
                    char edit[50];
                    cout << "Edit: ";
                    cin.getline(edit, 50);
                    for (int i = 0; i < countOfFlights; i++)
                    {
                        if (strcmp(flight_d[i].destination, edit) == 0)
                        {
                            //edit file
                        }
                    }
                }
            }       
        }

由于您的Flight_Details在写入时具有固定的字节大小,因此很容易计算每个航班在文件中的位置。一般方程是flight_number * sizeof(Flight_Details)//where flight_number is 0..N .这将计算要查找的文件的字节偏移量。从那里只需从文件中准确读取 sizeof(Flight_Details) 个字节并将该缓冲区转换为Flight_Details,在这种情况下,这可能意味着您只需手动用字节填充Flight_Details中的每个缓冲区,或者如果您愿意,您可以将数据char* reinterpret_cast()为正确的类型(只有当您的缓冲区正好CC_时,这才是一个不错的主意8 长。通过某种构造函数手动复制字节会更安全。

这是

您将在评论下写的内容// edit file。这看起来很丑,但工作得很好

cout << "Yeah we are editingn";
char newdestiny[99];
cout << "new dest: ";
cin.getline(newdestiny, 99);
strcpy(flight[i].destination, newdestiny);
file.write((char*)flight, sizeof(Flight_Details[countOfFlights]));
file.close();
return 0; 

而且你的程序中有一些错误,比如当你要求出发时,你会得到目的地,当你打开file来写入数据时,你必须包括ios::app标志,以便你也可以输入新的航班信息(?

我正在打开的文件只有ios::out标志

还有

一件事strcmp(flight_d[i].destination, edit) == 0这条线应该strcmp(flight[i].destination, edit) == 0