#include <string>
#include <iostream>
int main() {
std::string str;
char magic[9];
std::cin.read((char *)magic, sizeof(magic));
std::cin.seekg(0, std::ios::beg);
while (std::cin >> str) {
std::cout << str << std::endl;
}
}
我的代码包含 std::cin 上的 seekg(0) 函数的实现 它在某些文件上的行为不符合预期 运行时为./a.out < filename
那些没有按预期运行的文件具有字符数(包括尾行字符和其他空格)小于 9 的属性(9 是我们在 seekg 之前从 CIN 读取的字符数)
如果文件包含超过 9 个字符,则其行为符合预期 例如:
123456789
将输出为
123456789
而包含少于 9 个字符的文件不会给出输出
例如:
1234
将不提供输出
对于少于九个字符的文件,您已经尝试用初始read
阅读末尾。这意味着已经为流设置了eof
(文件末尾)和fail
标志,虽然seekg
可以重置eof
,但它不会重置fail
(a)。
您可以通过插入以下内容来检查:
cout << "eof/fail=" << cin.eof() << '/' << cin.fail() << 'n';
紧接在seekg
之前和之后.对于分别为 8、9 和 10 的文件大小,您将获得:
eof/fail=1/1
eof/fail=0/1
eof/fail=0/0
eof/fail=0/0
12345678
eof/fail=0/0
eof/fail=0/0
123456789
您可以看到第一次失败导致没有输出,因为fail
位仍在设置中。第二个和第三个有输出,因为它从未设置过(输出是显示的字符加上一个换行符)。
要解决此问题,您只需在seekg
之前插入以下内容即可清除fail
位:
std::cin.clear();
然后在八个字符的文件上运行该代码得到:
eof/fail=1/1
eof/fail=0/0
1234567
表明clear
确实清除了fail
位。
您可能还需要记住,流不是可搜索性的要求,特别是如果它只是通过标准输入传入。您可能会发现,对于某些大小的文件,如果您已经阅读了流的一大块,则无法回购任意数量的文件。
(a)对于我们中间的语言律师来说,Unformatted input functions
(C++11 27.7.2.3/41
、C++14 27.7.2.3/41
和C++17 30.7.4.3/41
)对seekg
如何运作都有基本相同的文本(我的强调):
构造一个哨兵对象后,如果 fail() != true,则执行...