【问题标题】:Why does seekp/seekg exist for std::fstream when they both move one single pointer?为什么当 std::fstream 都移动一个指针时存在 seekp/seekg?
【发布时间】:2021-06-11 08:15:57
【问题描述】:

以下代码将输出相同的位置:

std::fstream fp;
fp.open("somefilename", std::ios::in | std::ios::out | std::ios::ate);
if (!fp.good()) exit(1);
fp.seekp(100, std::ios::beg);
std::cout << "p: " << fp.tellp() << "  g: " << fp.tellg() << "\n";
fp.seekg(0, std::ios::beg);
std::cout << "p: " << fp.tellp() << "  g: " << fp.tellg() << "\n";

因此,假设文件存在并且至少包含 100 个字节,输出将是

p: 100  g: 100
p: 0  g: 0

我的问题是,为什么要坚持在 API 中使用两个指针,而实际上它们是相同的? 我知道继承会“降低”虚拟方法,但我认为这有点令人困惑,因为很容易犯错误,并且相信有两个单独的指针,一个用于读取(get),一个用于写入(put)不是。

是不是因为某些操作系统和/或硬件设备支持两个独立的指针?

为任何反馈干杯:-)

【问题讨论】:

  • 我的猜测是,basic_istream 和 basic_ostream 都作用于 basic_ios(或 ios_base)中的同一个数据成员。我对你的惊讶表示同情,这似乎也违反了 Liskov 原则。 en.cppreference.com/w/cpp/io/basic_fstream
  • @dratenik 我认为该链接没有解释“为什么”,它只是以官方方式说“它是”
  • @AlessandroTeruzzi 加上它提供了一个流(stringstream)示例,其中 put 和 get 位置是独立的。
  • @dratenik 我并不是说这个链接没有任何价值,确实让我很好奇为什么 stringstream 表现不同
  • @AlessandroTeruzzi 可能是底层操作系统的限制,我不认为任何主流操作系统(和/或 POSIX)都为文件描述符维护单独的读写位置。

标签: c++ c++-standard-library


【解决方案1】:

std::fstream 同时充当输入流和输出流。您可以编写以下代码:

void f(std::ofstream& out) {
    out.seekp(whatever);
}

void g(std::ifstream& out) {
    out.seekg(whatever);
}

void q(std::fstream& str) {
    f(str);
    g(str);
}

为了使其工作,std::fstream 必须同时提供 seekgseekp

这两个函数都操作同一个指针,因为操作系统不一定区分读取位置和写入位置。当流处理不是文件的资源(例如字符串)时,实现可以处理不同的读写位置,而无需复杂的操作。

【讨论】:

  • 所以真正的原因与继承有关。 fstream 继承自 iostream,iostream 继承自 istream 和 ostream,而 ofstream 仅继承自 istream 的 ostream 和 ifstream。所以也许他们选择这种方式来设计它是为了 API 的方便。我们有 iostream 和 fstream 只需要继承它并专门处理相同的指针。
猜你喜欢
  • 2013-03-18
  • 1970-01-01
  • 2012-03-10
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-29
相关资源
最近更新 更多