0
void updatebfile(char filename[MAX])
{

fstream writereadb;

char cont='y';
char filenameb [MAX];
int i=1;
int record;

student s;

strcpy(filenameb,filename);
strcat(filenameb,".dat");

writereadb.open(filenameb,ios::in | ios::out | ios::binary  );


cout<<"------------------------------"
    <<endl;

cout<<"Begin updating of binary file "
    <<filenameb
    <<endl
    <<endl;

cout<<"Information for student file"
    <<endl
    <<endl;


while ( writereadb.read (reinterpret_cast <char *>(&s), sizeof (s) ) )
{

    cout<<i
        <<'\t'
        <<s.identity
        <<" "
        <<s.name
        <<endl;

    i++;


}

do
{


cout<<endl
    <<"Update record: ";
cin>>record;

cout<<endl
    <<"Student id: ";



writereadb.seekg ((record - 1) * sizeof(s), ios::beg);//problem is here
writereadb.read (reinterpret_cast <char *>(&s), sizeof (s));//always reading last value


cout<<s.identity
    <<endl;





cout<<"Update the name: ";
cin>>s.name;



writereadb.seekp((record-1)*sizeof(student),ios::beg);  
writereadb.write (reinterpret_cast <const char *>(&s), sizeof (s));

cout<<"Any more update (y/n) :";
cin>>cont;

}while (cont=='y');

writereadb.close();







}

我有这个简单的功能,我想在其中更新二进制文件。问题是我似乎无法设置 get 指针,当我 cout s.identity 时,我总是在读取二进制文件中的最后一个值

4

1 回答 1

2

您总是尝试读取一个条目,并且仅在成功时才使用结果(这是完全正确的)。如果它没有成功,例如因为遇到 EOF,streamstate 将被设置为“fail”。这会导致读取循环终止,但也会导致对该文件流的任何后续操作失败,直到您明确重置流状态。因此,您需要writereadb.clear()在该循环之后调用。

还有一些注意事项:

  • 传递 achar filename[MAX]不会将数组传递给函数!相反,它与 a 相同char* filename,即修改该参数将使其在调用函数中可见。使用std::string,使用它们的c_str()成员函数来获取fstream.
  • 您没有读取最后一个值,您没有读取它!您的代码应该检测到这一点。此外,它似乎已经读取了最后一个值,因为您正在重用临时结构。一般来说,保持变量范围的大小尽可能小是个好主意。在函数开头声明所有变量的习惯属于旧时代(上个世纪),这对于 C 代码是必要的,但在 C++ 代码中则不然。在这种情况下,我什至可以想象将整个程序分成两个或三个函数。
  • Dumping structs to files is not portable between different computers, not even different compilers on the same computer sometimes. For that reason, there are multiple serialization libraries out there that do this correctly.
于 2013-01-13T09:46:27.880 回答