将文件指针定位在一条记录中

positioning the file pointer in a record

所以,这就是我书中给出的问题。

阅读下面的代码并回答下面给出的问题:

#include<fstream.h>

class Book
{

int Bno;char title[20];

public:
void Enterval()

{
cin>>Bno;

cin.getline(title,20);

}

void ShowVal()

{
cout<<Bno<<"#"<<title<<endl;

}

};

void Search(int Recno)

{
fstream file;
Book B;
file.open("BOOKS.DAT",ios ::binary|ios :: in);

______________// statement 1

file.read((char*)& B,sizeof(B));
B.ShowVal();
file.close();
}

1) 将文件指针指向要读取的所需记录的开头,该记录作为函数的参数发送(假设 RecNo 1 代表第一条记录)。

给出的答案是

file.seekg((RecNo-1)*sizeof(B));

我只想知道他们为什么写 (RecNo-1)。 打开文件时,文件指针是否位于文件末尾 是否指向记录的开头

我也想知道答案是否可以

file.seekg(-1*sizeof(B),ios::cur);

因为我们必须从记录的开头读取。

请告诉我是否正确,如果错误请指正。

感谢帮助。

谢谢!

要查找包含相同大小元素的文件,需要了解两件事:我的记录从哪里开始以及它有多大?两者都在语句

中编码
file.seekg((RecNo-1)*sizeof(B));

每条记录的大小

sizeof(B)

由于条目是由从 1 开始的书号标识的,并且第一个条目从文件中的第一个位置(即位置 0)开始,因此您必须从每个书号中减去 1 以获得 0-基于索引。与记录大小的乘积然后为您提供给定书籍的起始位置。

声明

file.seekg(-1*sizeof(B),ios::cur);

会导致当前文件指针向后移动一个记录大小的步长。但是打开文件后当前位置是0,已经是文件的开头了。此外,以这种方式实现的搜索功能永远不会使用给定的书号,导致它对您传递的每个书号都执行相同的操作。

我的猜测是 Search 函数的 Recno 参数的编号是 "one-based",即第一个元素由数字“1”标识.

另一方面,输入流位置是 "zero-based"(就像 C 和 C++ 中的几乎所有内容一样),即流中第一个可用的绝对位置由数字“0”标识。而且,如果要读取第1-stBook,就必须从文件的开头开始,所以要找位置:

position := stream_first_pos + (Recno-1)*size_of_what_recno_refers_to

也就是说,如果您想要第 1 本书,即 Recno == 1,您的位置将转到 stream_first_pos

自己提出的方案,即:

file.seekg(-1*sizeof(B),ios::cur);

不正确,因为它没有使流指向大小为 sizeof(Book) 的第 Recno 个块,但它只是移动流的当前位置(在您的情况下,0 ) "sizeof(B)" 个位置。

我认为 RecNo - 1 是因为作者想要 对文件的索引从 1 开始,而对文件的偏移量 从0开始。打开文件时,初始位置将在 文件的开头。并且

file.seekg( -1 * sizeof(B), ios::cur );

应该会失败,因为它会尝试在文件开始之前进行备份。

话虽如此,这段代码有很多错误, 很难开始。谁写的都不懂C++

打开文件时,文件指针将位于文件的开头。

对于第 N 条记录,语句将是

file.seekg((N-1)*sizeof(B));

这是因为要查看或编辑第 N 条记录,必须将指针移动到 N-1 条记录的末尾,然后读取它,这就是上面提到的代码所做的。

你提出的建议

file.seekg(-1*sizeof(B),ios::cur);

将不起作用,因为您刚刚打开文件并试图转到文件中第一个位置之前存在的位置,这是不可能的,因此此代码将不起作用。

希望这能解决您的问题