Lev*_*aya 2 c++ string exception
我在 C++ 中的异常处理方面遇到了一些问题。我需要将数字转换为字符串,如果该字符串包含字母或超过 10 个字符,我需要给出错误。这是异常处理部分;
while ( cin >> input )
{
try
{
convert = castInput( input );
cout << "The number entered was: " << convert;
}
catch ( NonNumber &excp )
{
cout << "INVALID INPUT: " << excp.what();
}
catch ( Overflow &excp )
{
cout << "INVALID INPUT: " << excp.what();
}
cout << "\n\nPlease enter a number (end-of-file to terminate): ";
}
Run Code Online (Sandbox Code Playgroud)
我使用 stoi 函数将字符串转换为 int 但我认为我需要打开 2 个类。我不知道为什么以及如何,因为 stoi 函数已经拥有什么功能。
我个人认为正则表达式对此并不过分。使用正则表达式检查用户输入不会对性能产生任何负面影响。
但我认为你对异常处理更感兴趣。您需要阅读一本优秀的 C++ 书籍的很多页才能了解异常处理及其用例。
也许,但我不知道,您只想捕获std::stoi引发的标准异常。这些都是:
写起来很容易
// Standard exceptions for stoi
catch (const std::invalid_argument & e) {
std::cout << e.what() << "\n";
}
catch (const std::out_of_range & e) {
std::cout << e.what() << "\n";
}
Run Code Online (Sandbox Code Playgroud)
但也许您想学习如何编写自己的异常。针对您的具体要求。但请注意,您的规范,例如“超过 10 位数字”和“无字母”可能并不完全是您想要的。对于一台机器,其中 int 是 32bit 位,可以转换的最大数字是:2147483647。任何更大的数字但仍然只有 10 个字符,都会抛出std::out_of_range. 另一方面,像 123X 这样的数字会转换std::stoi为 123。所以,也许您的要求不太清楚。
不管怎样,为了向您展示如何使用自己的异常,我创建了 2 个自定义异常类。为了让生活变得简单,我从 std::exception 派生了它们(推荐)。
请参阅下面的示例:
#include <iostream>
#include <string>
#include <algorithm>
#include <exception>
#include <cctype>
#include <vector>
#include <sstream>
class StoiException : public std::exception
{
public:
StoiException(const std::string& msg) : message(msg) {}
virtual const char* what() const noexcept override { return message.c_str(); }
protected:
void setMessage(const std::string& msg) { message = msg; }
protected:
std::string message{};
};
class NoNumber : StoiException
{
public:
NoNumber(const std::string& msg) : StoiException(msg) { setMessage(std::string("My Exception -> NoNumber: ") + msg); }
virtual const char* what() const noexcept override { return message.c_str(); }
};
class Overflow : StoiException
{
public:
Overflow(const std::string& msg) : StoiException(msg) { setMessage(std::string("My Exception -> Overflow: ") + msg); }
virtual const char* what() const noexcept override { return message.c_str(); }
};
int castInput(std::string& input) {
int result{};
// Check, if there is any letter in the input string
if (std::any_of(input.begin(), input.end(), isalpha)) {
// If so, than throw
throw NoNumber(input);
}
// Check, if string has more than 10 characters
if (input.length() > 10) {
// If so, than throw
throw Overflow(input);
}
result = std::stoi(input);
return result;
}
std::istringstream testCin{ R"(123
567
2147483647
2147483648
123X
12345678901
xyzxyzxyzxyzxyz
)" };
int main() {
std::string input{};
// Read all input
while (testCin >> input) {
try {
// Convert
int convert = castInput(input);
// This will only be shown , if there is no exception
std::cout << "\nConverted Number is: " << convert << "\n";
}
// Catch all exceptions
catch (const NoNumber & e) {
std::cout << e.what() << "\n";
}
catch (const Overflow & e) {
std::cout << e.what() << "\n";
}
// Standard exceptions for stoi
catch (const std::invalid_argument & e) {
std::cout << e.what() << "\n";
}
catch (const std::out_of_range & e) {
std::cout << e.what() << "\n";
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当然,您std::stoi也可以在自定义转换器函数中处理 的异常。那么只有你自己的异常是可见的。
请参见:
#include <iostream>
#include <string>
#include <algorithm>
#include <exception>
#include <cctype>
#include <vector>
#include <sstream>
class StoiException : public std::exception
{
public:
StoiException(const std::string& msg) : message(msg) {}
virtual const char* what() const noexcept override { return message.c_str(); }
protected:
void setMessage(const std::string& msg) { message = msg; }
protected:
std::string message{};
};
class NoNumber : StoiException
{
public:
NoNumber(const std::string& msg) : StoiException(msg) { setMessage(std::string("My Exception -> NoNumber: ") + msg); }
virtual const char* what() const noexcept override { return message.c_str(); }
};
class Overflow : StoiException
{
public:
Overflow(const std::string& msg) : StoiException(msg) { setMessage(std::string("My Exception -> Overflow: ") + msg); }
virtual const char* what() const noexcept override { return message.c_str(); }
};
int castInput(std::string& input) {
int result{};
// Check, if there is any letter in the input string
if (std::any_of(input.begin(), input.end(), isalpha)) {
// If so, than throw
throw NoNumber(input);
}
// Check, if string has more than 10 characters
if (input.length() > 10) {
// If so, than throw
throw Overflow(input);
}
try {
result = std::stoi(input);
}
// Standard exceptions for stoi
catch (const std::invalid_argument & e) {
throw NoNumber(input);
}
catch (const std::out_of_range & e) {
throw Overflow(input);
}
return result;
}
std::istringstream testCin{ R"(123
567
2147483647
2147483648
123X
12345678901
xyzxyzxyzxyzxyz
)" };
int main() {
std::string input{};
// Read all input
while (testCin >> input) {
try {
// Convert
int convert = castInput(input);
// This will only be shown , if there is no exception
std::cout << "\nConverted Number is: " << convert << "\n";
}
// Catch all exceptions
catch (const NoNumber & e) {
std::cout << e.what() << "\n";
}
catch (const Overflow & e) {
std::cout << e.what() << "\n";
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但也许,您真正想要的是一个函数,它封装std::stoi并有一个额外的返回值来显示,无论它是否有效。
请注意:最后一个解决方案还将“123X”转换为123。这是与之前版本的区别。
#include <iostream>
#include <string>
#include <algorithm>
#include <exception>
#include <cctype>
#include <vector>
#include <sstream>
std::pair<bool, int> castInput(std::string& input) {
bool ok{ false };
int result{};
try {
result = std::stoi(input);
ok = true;
}
// Catch stoi errors
catch (const std::invalid_argument & e) {}
catch (const std::out_of_range & e) {}
return {ok, result};
}
std::istringstream testCin{ R"(123
567
2147483647
2147483648
123X
12345678901
xyzxyzxyzxyzxyz
)" };
int main() {
std::string input{};
// Read all input
while (testCin >> input) {
const auto [ok, convert] = castInput(input);
if (ok)
std::cout << "Converted value: " << convert << "\n";
else
std::cout << "String '" << input << "' could not be converted\n";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18550 次 |
| 最近记录: |