如何获取标准文件流以返回有用的错误消息? [英] How can I get the standard file streams to return a useful error message?

查看:131
本文介绍了如何获取标准文件流以返回有用的错误消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不能删除自己的问题,尝试覆盖...

cannot delete my own question, try to overwrite instead...

推荐答案

C ++ 11解决方案



由于C ++ 11, std :: ios_base :: failure 继承自 std :: system_error ,所以我们应该能够 catch 该异常,并从中获取错误消息。

The C++11 solution

Since C++11, std::ios_base::failure inherits from std::system_error so we should be able to catch that exception and get the error message right out of it.

#include <cstdlib>       // EXIT_SUCCESS, EXIT_FAILURE
#include <fstream>       // std::ifstream
#include <iostream>      // std::cerr, std::endl
#include <system_error>  // std::system_error


int
main()
{
  const auto filename = std::string {"/no/such/file.txt"};
  try
    {
      auto istr = std::ifstream {filename};
      istr.exceptions(std::ios::badbit | std::ios::failbit);
      // ...
      istr.close();
    }
  catch (const std::ios_base::failure& e)
    {
      std::cerr << "error: " << e.what() << std::endl;
      //std::cerr << "error: " << e.code().message() << std::endl;
      return EXIT_FAILURE;
    }
  return EXIT_SUCCESS;
}

不幸的是,这并不适用于我的GCC 5.3.0。 catch 永远不会被激活,而是转换程序的核心转储。更糟糕的是,这意味着我们必须 catch std :: exception 这也将匹配所有其他类型可能与I / O错误无关的异常。这真的让我很困扰。

Unfortunately, this doesn't work with my GCC 5.3.0 yet. The catch never gets activated and the program core-dumps instead. What is even worse is that this means we have to catch std::exception which will also match all other kinds of exceptions that might not be related to I/O errors. This really bothers me.

如果一切都失败,您可以使用'ye good ol' errno 并通过 std ::获取一个人类可读的字符串strrror (这不是线程安全的)。也不能保证在发生错误的点与处理异常的点之间没有清除(或重新分配) errno 。这是因为在C ++中,任意代码可能在堆栈展开期间执行。

If everything else fails, you can use 'ye good ol' errno and obtain a human-readable string via std::strerror (which is not thread-safe, by the way). There also is no guarantee that errno hasn't been cleared (or re-assigned) between the point where the error occurred and the point you handle the exception. This is because in C++, arbitrary code might have been executed during stack unwinding.

#include <cerrno>        // errno
#include <cstdlib>       // EXIT_SUCCESS, EXIT_FAILURE
#include <cstring>       // std::strerror
#include <exception>     // std::exception
#include <fstream>       // std::ifstream
#include <iostream>      // std::cerr, std::endl


int
main()
{
  const auto filename = std::string {"/no/such/file.txt"};
  try
    {
      auto istr = std::ifstream {filename};
      istr.exceptions(std::ios::badbit | std::ios::failbit);
      // ...
      istr.close();
    }
  catch (const std::exception&)
    {
      std::cerr << "error: " << std::strerror(errno) << std::endl;
      return EXIT_FAILURE;
    }
  return EXIT_SUCCESS;
}



使用 std :: error_code s



这个解决方案只是比使用 std :: strerror(errno)更好,但至少它看起来更像是C ++ 11。问题是相同的,除了它是线程安全的。

Using std::error_codes

This solution is only marginally better than using std::strerror(errno) but at least it looks more like C++11. The problems are the same except that it is thread-safe.

#include <cerrno>        // errno
#include <cstdlib>       // EXIT_SUCCESS, EXIT_FAILURE
#include <exception>     // std::exception
#include <fstream>       // std::ifstream
#include <iostream>      // std::cerr, std::endl
#include <system_error>  // std::error_code, std::system_category


int
main()
{
  const auto filename = std::string {"/no/such/file.txt"};
  try
    {
      auto istr = std::ifstream {filename};
      istr.exceptions(std::ios::badbit | std::ios::failbit);
      // ...
      istr.close();
    }
  catch (const std::exception&)
    {
      const auto ec = std::error_code {errno, std::system_category()};
      std::cerr << "error: " << ec.message() << std::endl;
      return EXIT_FAILURE;
    }
  return EXIT_SUCCESS;
}

这篇关于如何获取标准文件流以返回有用的错误消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆