【问题标题】:Verifying data type during parsing (string to int) in c++在c ++中解析(字符串到int)期间验证数据类型
【发布时间】:2014-07-16 22:07:22
【问题描述】:

我正在尝试测试将字符串转换为整数,以确保字符串中的数据实际上是属于整数的数据。 (例如,用户输入 '!!!!' 所以我不希望它进入 int)。

我遇到的问题是,我希望能够在检测到无法进行转换后立即以某种方式抛出错误。我想在演员阵容期间或之后对其进行测试的原因是因为我需要用户的输入才能首先转到一个字符串。

我首先尝试执行“选项 1”,但我注意到会弹出某种调试错误,它不允许我抛出自己的错误并显示对用户更友好的错误。

然后我正在尝试选项 2(我认为我可以将验证包裹在演员表周围)但是当我观察变量类型时,它通过了选项 2,即使它显示为字符串并且我的代码似乎没有捕捉到它不是 int,因此抛出我的错误

我只会使用这两个选项之一,并清楚地注意两者。我只是把我的两个电子都放了

using namespace std;
#include <string>
#include <iostream>
#include <typeinfo>

int main()
{
string employeeNumber;
string hoursWorked;
int newEmployeeNumber;


cout << "What is your employee number?" << endl;
cin >> employeeNumber;

//CONVERT AND VERIFY CAST/CONVERSION OCCURRED SUCCESSFULLY
//IF NOT (ex. user entered '!!!' so it shouldnt be able to cast to int..
//THEN THROW MY ERROR


//option 1
newEmployeeNumber = stoi(employeeNumber);
throw MyErrorThatDoesntGetReached("notan int");
//(will throw its own error right there and I can't let it throw mine after


//option 2
if (typeid(stoi(employeeNumber)) != typeid(int) )
            throw Exception("data in file is CORRUPT");



}

【问题讨论】:

  • 为什么不在第一个地方声明 employeeNumberint
  • 检查输入操作的结果到int。如果您需要检查整个字符串,使用一个参数调用stoi 不会删除它。
  • 捕捉 stoi 的异常,抛出你自己的。

标签: c++ validation


【解决方案1】:

Sleeper 的想法一点也不差。或者,我们可以捕获std::stoi() 在无效输入上抛出的异常:

#include <string>
#include <iostream>
#include <typeinfo>

using namespace std;

int main()
{
    string employeeNumber;
    string hoursWorked;
    int newEmployeeNumber;

    cout << "What is your employee number?" << endl;
    cin >> employeeNumber;

    try {
        newEmployeeNumber = stoi(employeeNumber);
    } catch (std::invalid_argument const & e) {
        throw MyException("The input couldn't be parsed as a number");
    } catch (std::out_of_range const & e) {
        throw MyException("the input was not in the range of numbers supported by this type");
    }
}

【讨论】:

  • 我必须在 catch 中使用 std::invalid_argument const & e 吗?我可以创建自己的异常类并进行尝试,然后只使用 catch(MyException class e){ do stuff} 吗?
  • 实际上,回答了这个问题——我怎么知道将来我需要捕获什么异常来处理我可能遇到的其他未来函数错误?我是新手,我不知道把 std::invalid_argumet const & e 放进去赶上
  • @user3389343:检查您正在调用的函数的文档。对于std::stoi(),文档报告它可以抛出这两个异常中的任何一个。
  • @user3389343:对于第一部分,您可以使用自己的异常类型。这就是我在这里展示的。 std::stoi() 将抛出这两个异常之一,然后您可以将它们包装在您自己的异常类型中并重新抛出它。
【解决方案2】:

为了测试一个值,我提供了正则表达式:

#include <string>
#include <conio.h>
#include <iostream>
#include <typeinfo>
#include <regex>

using namespace std;

bool isNumber( string val );

void main() {

    string employeeNumber;
    string hoursWorked;
    int newEmployeeNumber;


    cout << "What is your employee number?" << endl;
    cin >> employeeNumber;

    if ( isNumber( employeeNumber ) ) {
        newEmployeeNumber = stoi(employeeNumber);

        cout << "is number\n";
    }
    else {
        cout << "is not number\n";
    }

    getch();
}

bool isNumber( const string val ) {
    std::string templ("\\d*");

    if ( regex_match( val, std::regex(templ) ) ) {
        return true;
    }

    return false;
}

更新: IsNumber 函数的其他变体:

bool isNumber( const string val ) {

    for( int i = 0; i < val.length(); i++ ) {

        if ( !isdigit( val[i] ) ) {
            return false;
        }
    }

    return true;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    • 2017-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多