假设包含的文件使用命名空间 std 并包含 std 库设施。
我编写了一个程序,将坐标平面上的点写入某个输入文件流,然后使用该流将这些点添加到
vector<point>
对象;
我已经编写了写入输入文件流的程序,它运行良好,因为我可以看到我添加的点,因为我的文件有一个 .txt 扩展名,即 m.txt
这是我的代码
#include"../dumbheader.h.txt"
struct point {
int x=0;
int y=0;
point(int i,int j):x(i),y(j){}
point(){}
};
istream& operator>>(istream& is, point& p) { // input format accepted (int,int)
char ch1, ch2,ch3;
if (is >> ch1 && ch1 == '(') {
if (!(is >> p.x))
error(" an integer expected \n");
if (!(is >> ch2 && ch2 == ','))
error(" a ',' is expected ");
if (!(is >> p.y))
error(" bad second argument \n");
if (!(is >> ch3 && ch3 == ')'))
error(" ) expected \n");
}
else error(" ( expected ");
return is;
}
ostream& operator<<(ostream& os, const point& p) {
os <<'(' <<p.x << "," << p.y<<')';
return os;
}
vector<point>vp;
void printv(vector<point>v) {
for (auto x : v)
cout << x << endl;
}
void end_of_loop(istream& ist, char term, const string& message)
{
if (ist.fail()) { // use term as terminator and/or separator
ist.clear();
char ch;
if (ist >> ch && ch == term) return; // all is fine
error(message);
}
}
int main()try{
vector<point>pp;
{
ifstream ifs{ "m.txt" };
for (point p; ifs >> p;)
pp.push_back(p);
}
printv(pp);
}
catch (runtime_error& e) {
cout << e.what();
}
我省略了写入 m.txt 的代码,以免我必须重复将点写入文件,但是代码工作正常并且文件具有文本:(1,1)(2,2)(3, 3)(4,4)。 代码的输出:(预期 C:\用户bdua\源 epos\DrillsOnChap10Points\x64\Debug\DrillsOnChap10Points.exe(进程 21104)退出,代码为 0。 按任意键关闭该窗口。 。 。 我不明白的是为什么我收到此消息,该文件似乎不错。
我在输入函数中添加了一个 static int ,通过在调用 error() 之前输出整数来写入调用它的次数,后者会抛出运行时错误。整数始终大于文件中元素的数量,就好像输入循环尝试读取文件末尾之外的内容。 此时我很困惑为什么会出现这种情况;因为如果我理解正确的话,输入文件流应该在其关联的范围结束时关闭。 编辑:
我已将 main 内的范围更改为
{
ifstream ifs{ "m.txt" };
int i = 1;
for (point p; ifs >> p&&i<=3;i++)
pp.push_back(p);
}
代码输出开头的三个点。问题似乎出在第四次阅读上;将 i 的测试更改为 i<=4 will cause the same problem.
TLDR: 读取时流最终处于失败状态
is >> ch1
使其返回 false,因为您已到达文件末尾(没有更多内容可读取)。
当您阅读
point
时,您会这样做
if (is >> ch1 && ch1 == '(') {
...
}
else {
error(" ( expected ");
}
当您使用 >>
的
ifstream
运算符(技术上更通用的 istream
) 时,它返回流本身,然后在 bool
上执行 istream
运算符,如果满足以下条件,则返回 false流处于 fail-state(设置 failbit
或 badbit
)。正如 istream::operator >>
参考中提到的,如果您尝试将当前输入从流读取到对象中但读取失败(例如,如果输入无法解析为该对象类型),则可能会处于这种状态。 ,
在您的代码中,您假设在尝试读取
(
时遇到了错误的字符并且失败了,但真正发生的情况是,当流到达 end 时,您试图将输入读取到对象中 - of-file(即没有更多内容可供阅读)。
您应该对此进行检查,无论是在 for 循环中,还是在 point
解析中,当到达文件末尾时让它失败:
if (is >> ch1 && ch1 == '(') {
...
}
else if (is.eof()) {
return is;
}
else {
error(" ( expected");
}
还有... 请注意其他评论提到的建议。如何发布您的问题 - 如果更容易复制您的问题,您就更有可能得到答案。我无法复制粘贴您的代码并运行它(即它不是一个最小的可重现示例)。