处理将字符串转换为整数的函数中的错误

时间:2016-10-21 21:30:59

标签: c++

我只是尝试将自己的函数实现为int转换的字符串。 我的功能如下:

int func(string s)
{
    if error return -1;
    else do something and return the value 
}

我只有一个疑问,如果我的字符串是s =" -1",那么我如何区分" -1"为错误和字符串的正确转换返回。谢谢你的帮助。我希望我的问题很清楚。

4 个答案:

答案 0 :(得分:3)

您有多种选择可以进行不同的权衡。

<强> 1。例外即可。在错误情况下抛出异常。不需要直接在调用站点捕获异常,但可以在调用层次结构中进一步处理异常,其中您有更多上下文来处理错误。我甚至会说,如果你总是在try-catch块中包装你的函数调用,你可能会误解异常的优势。

int func(const std::string& s);

<强> 2。可选的返回值。 std::optional,可在C ++ 17中使用(或在boost::optional或技术规范(TS)之前使用)。这是明确声明不返回值是在调用函数时必须考虑的有效情况。

std::optional<int> func(const std::string& s);

很酷的是显式的操作符bool允许这个习语:

if (std::optional<int> i = func("hello")) // or even auto
       use(*i);

第3。指针返回值。使用类似于前一点的语义,当返回存储的元素时,例如,这可能是需要的。在搜索中。如果未找到,则返回nullptr。与std::optional相反,它的缺点是它需要内存/生命周期管理(要么保证对象超过调用,要么动态分配)。如果确实需要使用std::unique_ptr动态分配,请不要返回必须由调用者显式删除的指针。请记住,动态分配是昂贵的,并且对int等小对象几乎总是过度杀伤。此外,您需要考虑const正确性。

int* func(const std::string& s);
const int* func(const std::string& s);
std::unique_ptr<int> func(std::string& s);

<强> 4。检查和输出参数习惯用法。有一个带输出参数的函数。如果它生成一个值,它会将结果写入该参数并返回true,否则返回false。

bool func(int& out);

这允许调用如下。缺点是您不能直接初始化对象(因此不能使用const - 限定,默认构造或不可分配的对象,例如)。

int value;
if (func(value))
    use(value);

<强> 5。断言即可。这是许多人忽略的事情,特别是那些来自Java等语言的人,大多数错误都是以异常方式明确处理的。如果唯一一个返回无效值的情况是函数的错误调用 - 即程序中的逻辑错误(不是说bug) - 那么通常更可取的是尽快识别它。调试器将在失败的断言时立即停止,而您的高效代码随之完全优化。

int func(const std::string& s);

断言非常适合检查函数的前置或后置条件。它们对于发出在运行时无法有意义处理的错误信号特别有用。如果它们失败,则意味着您的程序逻辑被破坏,并且由于这不应该首先发生,因此没有好办法从情况中恢复。由于您的应用程序处于意外状态,执行更多代码可能会使事情变得更糟。

答案 1 :(得分:1)

您的功能设计可能是:

int func(string s, int *out)
{
    if error return -1;
    else {
        do something and set *out to the value;
        return 1;
    }
}

正如评论所概述的那样,如果要表示有效值和错误,则-1的返回值会重载。由于没有可以表示两者的整数值,因此需要额外的返回值。在此设计中,函数的返回值表示成功或失败,*out参数返回结果。你可以交换这两个(参数接收成功或失败,返回值是值)。

答案 2 :(得分:1)

你可以抛出异常。

int func (string const & input)
{
  if (error)
    throw std::runtime_error("stuff happenend")
  else
    return value;
}

答案 3 :(得分:0)

我会使用boost::lexical_cast并让来电者处理bad cast exceptions

// will throw bad_lexical_cast  if any issue.
int convert(const std::string& num) {
    return boost::lexical_cast<int>(num);
}


int main()
{
    try {
        std::cout << convert("1") << "\n";
        std::cout << convert("-1") << "\n";
        std::cout << convert("abc") << "\n";
    } catch (const boost::bad_lexical_cast& blc) {
        std::cout << blc.what() << "\n";
    }

 return 0;
}

这很简单且经过充分测试。

更简单的方法是使用boost::lexical_cast<T>()而不使用convert函数,它只为您提供包装器;

试试here