Raf*_*ssi 1 c++ delphi exception try-catch
我是C++的新手,我来自一个Delphi场景,在这个场景中,我能够捕获异常,甚至无需声明显式throw.看看这里:
#include<iostream>
#include<exception>
int main() {
try {
int c;
std::cin >> c;
} catch(...) {
std::cerr << "Warning!" << std::endl;
char xz; std::cin >> xz;
return 1;
}
char z; std::cin >> z;
return 0;
}
//I return 1 because UNIX OS cares about this, a return != 0 means that Huston we have a problem
Run Code Online (Sandbox Code Playgroud)
我已经看到一些异常(例如除零)不会被自动捕获,所以我必须自己创建一个throw将在我的try-block中捕获的肯定.
如果你看一下上面的代码,当我第一次输入6.7或者test我应该能够在输出上看到warning!,但什么都没有.我在Windows 10机器上运行.
我知道这catch(...)是一般的,并给我肯定的保护,但为什么不抓错了输入?
注意.我上面提到过Delphi,因为如果你看下面的代码,我就能发现错误.
try
a := StrToInt('6.78'); //conversion error [string->double], a is int
ShowMessage('a is ' + a.ToString);
except
on E: Exception do
ShowMessage('Warning! > ' + e.Message);
//^ raises "Warning! > '6.78' is not a valid integer value."
end;
Run Code Online (Sandbox Code Playgroud)
为什么我不能用C++产生相同的效果?我知道它们是两种不同的语言,但起初我会说德尔福更好地"对待"异常.例如,它会自动捕获除以零(见下文),而c ++不会.
//this raises the "Division by zero" error.
a := 8 div StrToInt('0');
Run Code Online (Sandbox Code Playgroud)
结论.所以问题是:我try-catch是否正确地声明了C++ ?我是否总是必须使用throw以确保错误将被捕获或我可以省略它一些?
如文档中所述,您需要设置异常掩码std::cin以使其抛出std::ios_base::failure:
#include <iostream>
int main() {
std::cin.exceptions( std::ios::failbit );
try {
int i = 0;
std::cin >> i;
std::cout << "i=" << i << std::endl;
}
catch(...) {
std::cerr << "error!" << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我是否总是必须使用throw以确保错误将被捕获或我可以省略它一些?
是的,您需要调用异常throw.虽然库可能会因为错误条件(包括标准条件)而调用throw,但它可能抛出什么异常以及何时应该在文档中说明.
std::cin 当用户输入无效类型时,不会抛出.
假设C++ 11及更高版本,行为如下:
如果提取失败,则将零写入值并设置failbit.如果提取导致值太大或太小而不适合值,则写入std :: numeric_limits :: max()或std :: numeric_limits :: min()并设置failbit标志.
来自std::basic_istream::operator>>.
要检查输入是否无效,您应该执行以下操作:
#include <cstdint>
#include <iostream>
std::int32_t main()
{
std::int32_t example;
std::cin >> example;
if (std::cin.fail())
{
std::cout << "Invalid input" << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
或者您也可以这样做:
#include <cstdint>
#include <iostream>
std::int32_t main()
{
std::int32_t example;
if (!(std::cin >> example))
{
std::cout << "Invalid input" << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)