如何获取标准文件流以返回有用的错误消息? [英] How can I get the standard file streams to return a useful error message?
问题描述
不能删除自己的问题,尝试覆盖...
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_code
s
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屋!