0

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

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

#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);

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

如果我是对的,请告诉我,如果错了,请纠正我。

帮助表示赞赏。

谢谢!

4

4 回答 4

2

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

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

每条记录都有大小

sizeof(B)

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

该声明

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

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

于 2015-02-09T11:33:44.817 回答
1

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

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

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

话虽如此,这段代码有很多问题,很难开始。写它的人不知道 C++。

于 2015-02-09T11:36:01.887 回答
1

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

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

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

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

你所提议的

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

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

希望这能解决你的问题

于 2015-02-09T11:46:33.453 回答
0

我的猜测是函数Recno参数的编号Search旨在“基于一个”,即第一个元素由数字“1”标识。

另一方面,输入流的位置是“从零开始的”(就像 C 和 C++ 中的几乎所有东西一样),即流中第一个可用的绝对位置由数字“0”标识。此外,如果你想读取 1-st Book,你必须从文件的开头开始,所以你应该寻找位置:

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

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

自己提出的解决方案,即:

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

不正确,因为它不会使流指向Recnosize 的 -th 块sizeof(Book),但它只是将流的当前位置(在您的情况下为 0)“sizeof(B)”位置向后移动。

于 2015-02-09T11:35:43.367 回答