【发布时间】:2018-01-05 01:13:42
【问题描述】:
我遇到了一个奇怪的问题。假设我正在读取这样的文件:
std::ifstream in("file.txt", std::ios::binary);
std::string text;
in.seekg(0, std::ios::end);
text.resize(in.tellg());
in.seekg(0, std::ios::beg);
in.read(&text[0], text.size());
当文件包含少于 4 个字符(即 "ab" 或 "abc")时会出现问题,但在其他情况下可以正常工作,即 "abcd" 或更大。
为什么tellg 在这种情况下返回-1(最终导致我的字符串抛出std::length_error)?
其他信息:
我正在使用 MSVC 15.5.3(如果不是最新版本,也是更现代的版本之一)。也使用 GCC 5.1 进行了复制。
等效的 C 风格不会出现此错误:
FILE* f = fopen("text.txt", "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
编辑:
failbit 是在第一次调用seekg 之前设置的,这意味着打开文件失败?为什么小于 3 字节的文件会出现这种情况...
【问题讨论】:
-
failbit和badbit在-1返回后的值是多少? -
@paxdiablo 我用更多信息编辑了这个问题。只设置了
failbit。我想在那之后的任何操作都是无效的。 -
如果无法打开该文件,则该文件不存在或不在当前目录中。文件的大小可能只是巧合。
-
DeiDei,是的,这是正确的,我们现在已经解决了为什么
tellg返回 -1 的问题。不幸的是,为什么failbit被设置为开放的根本原因仍然是个谜。我对此的最佳答案是“如果我知道的话” :-) 也许其他人可以帮忙。要快速检查路径,请尝试在代码中使用文件的全名,例如/path/to/file.txt。 -
在对其进行任何操作之前设置故障位的一种方法是重用流对象。如果之前使用流设置了故障位,并且您在关闭它并重新打开流之前没有清除它(即使打开不同的文件),故障位仍然设置。