有没有办法可以在 C++ 中编辑文件的中间

Posted

技术标签:

【中文标题】有没有办法可以在 C++ 中编辑文件的中间【英文标题】:Is there a way I can edit the middle of a file in C++ 【发布时间】:2021-08-03 07:54:05 【问题描述】:

我正在使用 C++ 开发一个项目,该项目需要我使用名为 CustomerAccounts 的结构来获取名称、地址、城市等信息。我使用了 do..while 循环来允许用户输入新记录,显示记录、更改帐户信息或删除帐户。

我的问题在于处理文件。我想知道如果用户选择更改帐户信息,或者如果他们决定删除帐户,我是否可以编辑文件的中间部分。

int main(int argc, char** argv) 
    int choice, customer=0;
    fstream file;
    CustomerAccounts account[10];
    file.open("output.txt");
    file<<"";
    file.close();
    
    do
        cout<<"1. Enter new records into file.\n";
        cout<<"2. Display an account's information.\n";
        cout<<"3. Delete an account.\n";
        cout<<"4. Change an account's information.\n";
        cout<<"5. Display contents of all accounts.\n";
        cout<<"6. Quit";
        cout<<"\n\nEnter your choice: ";
        cin >> choice;
            switch(choice)
                case 1:
                    file.open("output.txt", ios_base::app);
                    getInfo(account[customer]);
                    addToFile(account[customer], file, customer+1);
                    customer++;
                    file.close();
                    break;
                    
                case 2:
                    int num;
                    cout<<"Enter the account number you wish to see: ";
                    cin>>num;
                    displayAccount(account[num-1], num);
                    break;
                case 3:
                    int num2;
                    cout<<"Enter the account you want to delete: ";
                    cin>>num2;
                    account[num2-1].address="";
                    account[num2-1].balance="";
                    account[num2-1].city="";
                    account[num2-1].lastPay="";
                    account[num2-1].name="";
                    account[num2-1].phone="";
                    account[num2-1].state="";
                    account[num2-1].zip="";
                    for(int i=num2-1;i<customer+1;i++)
                        account[i-1].address=account[i].address;
                        account[i-1].balance=account[i].balance;
                        account[i-1].city=account[i].city;
                        account[i-1].lastPay=account[i].lastPay;
                        account[i-1].name=account[i].name;
                        account[i-1].phone=account[i].phone;
                        account[i-1].state=account[i].state;
                        account[i-1].zip=account[i].zip;
                    
                    break;
                case 4:
                    int num3;
                    cout<<"Enter the account you wish to change: ";
                    cin>>num3;
                    cin.ignore( numeric_limits <streamsize> ::max(), '\n');
                    cout << "Enter name: ";
                    getline(cin, account[num3-1].name);
                    cout << "Enter address: ";
                    getline(cin, account[num3-1].address);
                    cout << "Enter city: ";
                    getline(cin, account[num3-1].city);
                    cout << "Enter state: ";
                    getline(cin, account[num3-1].state);
                    cout << "Enter zip: ";
                    getline(cin, account[num3-1].zip);
                    cout << "Enter phone number: ";
                    getline(cin, account[num3-1].phone);
                    cout << "Enter balance: ";
                    getline(cin, account[num3-1].balance);
                    cout << "Enter last pay: ";
                    getline(cin, account[num3-1].lastPay);
                    break;
                case 5:
                    file.open("output.txt");
                    string getContent;
                    cout<<"All Accounts: \n";
                    while(getline(file, getContent))
                        cout<<getContent<<endl;
                    cout<<endl;
                    break;
            

        while(choice!=6);
    return 0;

【问题讨论】:

除非您的文件包含固定大小的记录,并且您的编辑包括替换它们,1:1,这是不可能的,无论是在 C++ 还是在任何其他语言中,您都必须写出一个新文件,从头开始,从头到尾。 ...当您开始构建自己的数据库时,Sam 所说的非常完美。当您看到它开始工作时,它也很有趣。我说去吧。 @MarkRansom 这根本不是我的本意!?什么?我在 14 岁时就这样做了,并且很喜欢它。这并不是说不能做。恰恰相反!去做吧!可以的。 Yahya:我确实不是要关闭你的想法 - 恰恰相反,我很乐意提供帮助。 @TedLyngmo 我没有看到你的任何回复是残忍或粗鲁的。我很高兴能得到任何建议。 【参考方案1】:

您正在寻找的是seekp 链接中的示例非常有说服力。

#include <sstream>
#include <iostream>
 
int main() 
    std::ostringstream os("hello, world");
    os.seekp(7);
    os << 'W';
    os.seekp(0, std::ios_base::end);
    os << '!';
    os.seekp(0);
    os << 'H';
    std::cout << os.str() << '\n';

输出“你好,世界!”

现在你需要知道你的记录的大小(以字节为单位),我希望它们只包含固定类型而不包含指针。

当您要删除中间的记录时,可以用tombstone 标记它,这是您的记录不能包含的值,邮政编号。 -1 什么的。

如果你想在中间插入一条新记录,你有几个选择

将所有以后的记录下移一个 将其添加到末尾并继续使用它 创建索引以获得文件中的正确位置。

【讨论】:

以上是关于有没有办法可以在 C++ 中编辑文件的中间的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法将 c++ 编译器标志设为默认值

有没有办法通过管理面板编辑我的文件

有没有办法查看其他团队成员最近在 Cloud9 中编辑了哪些文件?

编辑单个 YAML 值而不更新 YAML 其余部分的格式(YAML CPP)[重复]

有没有办法摆脱原子编辑器中的选项卡行?

由于编辑器没有自动更新,有没有办法防止在 git pull 后意外覆盖?