输入流迭代器和异常

发布于 2024-08-23 07:05:07 字数 723 浏览 2 评论 0原文

几天前,我在玩 istream 迭代器和异常处理,我遇到了这个好奇:

#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>

using namespace std;

int main(int argc, char* argv[])
{
   if (argc < 2) {
      cout << argv[0] << " <file>" << endl;
      return -1;
   }

   try {
      ifstream ifs(argv[1]);
      ifs.exceptions(ios::failbit | ios::badbit);
      istream_iterator<string> iss(ifs), iss_end;
      copy(iss, iss_end, ostream_iterator<string>(cout, "\n"));
   }
   catch (const ios_base::failure& e) {
      cerr << e.what() << endl;
      return -2;
   }

   return 0;
}

为什么在读取输入文件的最后一个字后总是引发失败位异常?

I was playing around with istream iterators and exception handling a few days ago and I came across with this curiousity:

#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>

using namespace std;

int main(int argc, char* argv[])
{
   if (argc < 2) {
      cout << argv[0] << " <file>" << endl;
      return -1;
   }

   try {
      ifstream ifs(argv[1]);
      ifs.exceptions(ios::failbit | ios::badbit);
      istream_iterator<string> iss(ifs), iss_end;
      copy(iss, iss_end, ostream_iterator<string>(cout, "\n"));
   }
   catch (const ios_base::failure& e) {
      cerr << e.what() << endl;
      return -2;
   }

   return 0;
}

Why a failbit exception is always raised after reading the last word of the input file?

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

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

发布评论

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

评论(3

月野兔 2024-08-30 07:05:07

每当读取操作无法提取任何字符时,就会设置失败位,无论这是因为它是否达到了 EOF。

stringstream ss ("foo");
string s;
int i;

ss >> i; // sets failbit because there is no number in the stream
ss.clear();
ss >> s; // sets eofbit because EOF is hit
ss.clear();
ss >> s; // sets eofbit and failbit because EOF is hit and nothing is extracted.

failbit is set whenever a read operation fails to extract any characters, whether this is because it hit EOF or not.

stringstream ss ("foo");
string s;
int i;

ss >> i; // sets failbit because there is no number in the stream
ss.clear();
ss >> s; // sets eofbit because EOF is hit
ss.clear();
ss >> s; // sets eofbit and failbit because EOF is hit and nothing is extracted.
り繁华旳梦境 2024-08-30 07:05:07

好问题。如果能够捕获该调用中的其他失败,但在遇​​到 eof 时让它正常继续,那就太好了。

也就是说,我以前没有在流中使用过异常。我认为您可以进行复制并随后检查流的状态以检测其他错误,例如:

ifstream ifs(argv[1]);
if (!ifs) {
    cerr << "Couldn't open " << argv[1] << '\n';
    return -1;
}
//ifs.exceptions(ios::failbit | ios::badbit);
istream_iterator<std::string> iss(ifs), iss_end;
copy(iss, iss_end, ostream_iterator<std::string>(cout, "\n"));
if (!ifs.eof()) {
    cerr << "Failed to read the entire file.\n";
    return -2;
}

Good question. It would be nice to be able to catch other failures in that call, but have it continue normally when it hits eof.

That said, I haven't used exceptions with streams before. I think you could do the copy and check the state of the stream afterwards to detect other errors, for example:

ifstream ifs(argv[1]);
if (!ifs) {
    cerr << "Couldn't open " << argv[1] << '\n';
    return -1;
}
//ifs.exceptions(ios::failbit | ios::badbit);
istream_iterator<std::string> iss(ifs), iss_end;
copy(iss, iss_end, ostream_iterator<std::string>(cout, "\n"));
if (!ifs.eof()) {
    cerr << "Failed to read the entire file.\n";
    return -2;
}
七分※倦醒 2024-08-30 07:05:07

检测 EOF 条件的方法是读取直到发生故障(这会触发异常),然后检查故障原因。

扩展一下:当使用 >> 读取值后,流运算符 void* 返回 NULL 时,istream_iterator 变得无效。但为此,运算符>>必须设置失败位,因此引发异常。

One detect the EOF condition by reading until a failure -- which triggers the exception -- and then checking the cause of the failure.

To expand: the istream_iterator becomes invalid when after having read a value with >>, the stream operator void* returns NULL. But for that, the operator >> has to set the fail bit, so raise the exception.

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