C++ 在C++;std::streams,在发生故障后,如何获取故障原因?必需:线程安全,Windows和Linux通用(或至少Msvc/Gcc)
很抱歉这个奇怪的标题。限制为150个字符,因此无法使用正确的句子 假设我做了以下工作来发现我的文件流出现了问题:C++ 在C++;std::streams,在发生故障后,如何获取故障原因?必需:线程安全,Windows和Linux通用(或至少Msvc/Gcc),c++,c++11,error-handling,stream,iostream,C++,C++11,Error Handling,Stream,Iostream,很抱歉这个奇怪的标题。限制为150个字符,因此无法使用正确的句子 假设我做了以下工作来发现我的文件流出现了问题: std::ofstream ofs; do_stuff_with(ofs); // streams don't throw on error because C++ [edit: we can make them do so, but the .what()s aren't very user-friendly] // so we have to check for failure
std::ofstream ofs;
do_stuff_with(ofs);
// streams don't throw on error because C++ [edit: we can make them do so, but the .what()s aren't very user-friendly]
// so we have to check for failure manually
if(!ofs){
auto fail_code = errno; // threadsafe on Win/Linux
// but what goes here?
}
1) strerror:
不安全
2) 斯特雷罗:不在GCC?还是这样
3) 斯特雷罗:不在Msvc?还是这样
4) #ifdef/#define/etc:很恶心,但可能是唯一的选择
我确实做了一些搜索,但我没有找到一个“这肯定会以一种合理但稍微依赖于平台的方式工作”的答案。。。也就是说,我觉得这“显然是一个重复的问题”,但我找不到原始的…这是我能想到的最好的问题。这是“恶心”的答案,但至少你可以把“恶心”放在一个函数中,然后把它隐藏在某个cpp文件的某个地方。当然,ios也包括boost流 需要#ifdef所以这是个骗局。我相信visualstudio默认定义了WIN32,所以至少你不需要设置基础设施本身
void check_stream(std::ios & stream)
{
if (!stream){
char err[1024] = { 0 };
#ifdef _WIN32
strerror_s(err, errno);
#else
strerror_r(errno, err, 1024);
#endif
throw MyException(err);
}
}
我自己的解决方案让我很难过,所以希望会有更好的解决方案。但是时间是有限的,所以只要屈服于黑暗面,使用这样的东西,继续你的生活P
try{
boost::filesystem::ifstream ifs("testfile");
check_stream(ifs);
}
catch (std::exception & e){
std::cout << e.what(); // "No such file or directory"
}
试试看{
boost::filesystem::ifstream ifs(“testfile”);
检查流(ifs);
}
捕获(标准::异常&e){
std::cout您总是可以使用std::system\u error
抛出自己的异常:
#include <cerrno>
#include <fstream>
#include <iostream>
#include <system_error>
int main()
{
try
{
std::ofstream foo{"/root/bar.baz"};
foo << "bla" << std::endl;
foo.close();
if(!foo)
throw std::system_error{errno, std::generic_category()};
}
catch(const std::system_error& err)
{
std::cout << "Error: " << err.code() << " - " << err.what() << std::endl;
}
return 0;
}
#包括
#包括
#包括
#包括
int main()
{
尝试
{
std::of stream foo{“/root/bar.baz”};
foo自C++11以来,您可以使用类std::error\u code
来实现:
std::cout << std::error_code{errno, std::generic_category()}.message();
<代码> STD::CUT如果你想,可以让流丢到错误。C++中最接近的是。它不是保证有一个有用的<代码>()(<)/代码>。我知道异常()。但是出于某种原因,我也认为它没有被正确地实现。但是它似乎起作用,只是它给出了类似的消息。“ios_base::failbit set”而不是“没有这样的文件或目录”。正如stackoverflow上的其他地方所发现的那样,签出抛出,什么()
,try
和catch
。我想std::system\u错误可能就是我一直在寻找的!我会尝试这个,然后如果结果满足我的要求,我会将它标记为答案。我编辑了一个代码片段,以便在不通过异常的情况下获取错误消息,因为我的主要问题之一是获取一条可读的消息ut(而不是抛出异常,尽管这也很有用)。
std::cout << std::generic_category().message(errno);