您可以在哪些类型的输入流上调用eekg?

发布于 2024-12-05 18:28:57 字数 1066 浏览 2 评论 0原文

我有一个函数(遗留),它读取文件的前几行以确定其类型,然后关闭并重新打开该文件,以便它可以使用正确的解释器重新读取整个文件。要点是:

void readFile(const char *filename) {
  ifstream is(filename);
  Filetype ft = determineFileType(is);
  is.close();
  is.open(filename);
  parseFile(is, ft);
}

我需要一个可以在已经打开的流上工作的类似函数。我创建了一个新函数,它采用 ostream & 而不是 char *filename - 基本上是这样的:

void readFile(istream &is) {
  std::ios::streampos pos = is.tellg();
  Filetype ft = determineFileType(is);
  is.seekg(pos);
  parseFile(is, ft);
}

istream 时,它似乎可以工作实际上是一个 stringstream 或 fstream 但我想知道我是否只是运气好。我还对 seekg-ing std::cin 做了一个小测试,它成功了,这让我感到惊讶。

所以我的问题:您可以在哪些类型的流上使用seekg?什么时候会失败?规范参考会很棒 - 我浏览了一下,发现 seekkgpubseekposseekposseekoff 上的内容都不是根本没有帮助。

我想根据新功能重新实现原始功能(如下所示),但我只是不知道这是否安全。

void readFile(const char *filename) {
  ifstream is(filename);
  readFile(is);
  is.close();
}

I have a function (legacy) that reads the first few lines of a file to determine its type, then closes and reopens the file so it can re-read the entire file using the correct interpreter. The gist is:

void readFile(const char *filename) {
  ifstream is(filename);
  Filetype ft = determineFileType(is);
  is.close();
  is.open(filename);
  parseFile(is, ft);
}

I needed a similar function that can work on an already-opened stream. I created a new function that takes an ostream & instead of a char *filename -- basically this:

void readFile(istream &is) {
  std::ios::streampos pos = is.tellg();
  Filetype ft = determineFileType(is);
  is.seekg(pos);
  parseFile(is, ft);
}

It seems to work when the istream is actually a stringstream or an fstream but I wonder if I'm just getting lucky. I also did a small test on seekg-ing std::cin and it worked, which surprised me.

So my question: what kinds of streams are you allowed to use seekg on? When will it fail? Spec references would be great -- I looked through and the stuff on seekg, pubseekpos, seekpos, seekoff weren't helpful at all.

I'd like to reimplement the original function in terms of the new (as below), but I just don't know if that's safe.

void readFile(const char *filename) {
  ifstream is(filename);
  readFile(is);
  is.close();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ゞ记忆︶ㄣ 2024-12-12 18:28:57

人们能给出的唯一真正的答案是它在它起作用的地方起作用。在
对于 std::stringbuf 来说,它应该可以在任何地方工作。如果是
std::filebuf,是否有效取决于系统;它将
如果 filebuf 在实际文件上打开,通常可以工作,但会
通常会失败(如果系统没有报告错误,可能会默默失败)
对于许多其他类型的输入:来自键盘或命名管道,例如
例子。

更可靠的解决方案是缓存初始输入,然后从缓存中重新读取它。

The only real answer one can give is that it works where it works. In
the case of std::stringbuf, it should work everywhere. In the case of
std::filebuf, whether it works or not depends on the system; it will
generally work if the filebuf is opened on an actual file, but will
usually fail (perhaps silently, if the system doesn't report an error)
for many other types of input: from a keyboard, or a named pipe, for
example.

A more robust solution would be to cache the initial input, and re-read it from the cache.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文