修改二进制文件中的字符串等动态数据

时间:2017-08-20 13:36:40

标签: c++

我有一个二进制文件,其中包含学生的记录,其中每个记录都是Student定义为的类的实例:

class Student
{
   string idno, sname;
   int books_issued;
   vector<string> bname;
   public:
      void save(fstream &of);
      void load(fstream &inf);
      void modify_student()
      {
           cout<<"ID No:\t"<<idno<<"\n";
           cout <<"Modify Student's Name:\n";
           cout<<"Enter name:\t";
           cin.ignore();
           getline(cin, sname);
}
      //Some more code here
};

我正在使用保存成员函数在文件中写入记录:

void save(fstream &of)
{
    unsigned len = idno.size();
    of.write((char *)&len, sizeof(len));
    of.write(idno.c_str(), len);

    len = sname.size();
    of.write((char *)&len, sizeof(len));
    of.write(sname.c_str(), len);

    of.write((char *)&books_issued, sizeof(books_issued));

    len = bname.size();
    of.write((char *)&len, sizeof(len));
    int i = 0;
    while(len>0)
    {
        unsigned strlen = bname[i].size();
        of.write((char *)&strlen, sizeof(strlen));
        of.write(bname[i].c_str(), strlen);
        i++;
        len--;
    }
}

使用load函数从文件中读取记录,该函数也返回读取记录的大小:

 unsigned int load(fstream& inf)
 {
    unsigned finalLength = 0;
    unsigned len;
    inf.read((char *)&len, sizeof(len));
    if(len>0)
    {
        char *buf = new char[len+1];
        inf.read(buf, len);
        buf[len] = '\0';
        idno= buf;
        delete[] buf;
    }
    finalLength+=(len+sizeof(len));

    inf.read((char *)&len, sizeof(len));
    if(len>0)
    {
        char *buf = new char[len+1];
        inf.read(buf, len);
        buf[len] = '\0';
        sname = buf;
        delete[] buf;
    }
    finalLength+=(len+sizeof(len));

    inf.read((char *)&books_issued, sizeof(books_issued
    finalLength+=(sizeof(books_issued));

    bname.erase(bname.begin(), bname.end());
    inf.read((char *)&len, sizeof(len));
    finalLength+=(len);
    while(len>0)
    {
        unsigned strlen;
        inf.read((char *)&strlen, sizeof(strlen));
        if(strlen>0)
        {
            string str;
            char *buf = new char[strlen+1];
            inf.read(buf, strlen);
            buf[strlen] = '\0';
            str = buf;
            bname.push_back(str);
            delete[] buf;
        }
        finalLength+=(strlen+sizeof(strlen));
        len--;
    }

    return finalLength;
}

读取和写入操作已成功执行,但在尝试修改记录时,它会显示意外行为:

 void modify_specific_student()
 {
     string studentid;
     cout<<"Enter id no:\t";
     cin>>studentid;
     fstream fp;
     fp.open("student.dat", ios::binary|ios::in|ios::out);
     student st;
     int found = 0;
     if(fp.is_open())
     {
         while(!fp.eof())
         {
             unsigned int len = st.load(fp);
             cout<<"Length: "<<len<<"\n";
             if(!fp.eof())
             {
                  if(st.searchByIdNo(studentid))
                  {
                     st.show_personal_details();
                     st.modify_student();
                     unsigned int pos = -1*len;
                     fp.seekp(pos,ios::cur);
                     st.save(fp);
                     cout<<"Record Updated\n";
                     found = 1;
                  }
            }
         }
     }
    fp.close();
     if(!found)
    cout<<"Record not found\n";
 }

在我看来,问题出现了,因为新字符串可能具有不同的大小,并且需要移动后续数据(和记录)。如果这是原因,如何纠正,或者如果没有,实现记录的修改?

0 个答案:

没有答案