strtod 在同一变量上没有给出一致的结果

strtod not giving consistent results on same variable?

本文关键字:结果 变量 strtod      更新时间:2023-10-16

我正在学习 c++,并通过一些示例练习进行操作。特别是这个接受命令行参数,然后对它们进行数学运算,这样如果我输入

./ex1 sum 1.0 2.0 3.0

它应该总结这些数字。我的代码是这样的:

int main(int argc, char* argv[])
{
    double print_val;
    //if we want a sum
    print_val = sum(argc, argv);
    cout << print_val << endl;
}

然后,后来,我有

double sum(int argc, char* argv[]){
    double return_val = 0;
    for(int i =2; i< argc; i++){
        return_val += strtod(argv[i], &argv[i]);
    }
    return return_val;
}

不过出于某种原因,我只得到 0。当我进行调试时,我可以看到 strtod 正在通过返回双精度

cout << strtod()
and
cout << strtod() + 1.0

它们都会产生预期的结果,但如果在 for 循环中我放入

cout << return_val

每次分配后,它显示为 0。我什至尝试将其初始化为 return_val 到 1.0 无济于事(每次同一行输出 1(。

我最初在主中拥有此代码,并且它有效。我将其复制/粘贴到此功能中,现在它不起作用。我做错了什么?

完整的文件,就像它目前一样(有很多调试功能((对不起,缩进很不稳定,我也是第一次学习 vim,它在 vim 中看起来是正确的(:http://paste.ubuntu.com/8320413

strtod(argv[i], &argv[i])

这会将argv[i]转换为double,并将指向字符串其余部分的指针存储在 argv[i] 中。在您的情况下,它将是一个空字符串,因为整个字符串都用于转换。

这意味着您只能对每个值调用一次 i 。如果调试代码的某些部分以这种方式执行调用,则所有具有相同i的后续调用都将尝试从空字符串中提取double并失败。

没有必要这样做,只需为第二个参数传递一个空指针:

strtod(argv[i], nullptr) // C++11
strtod(argv[i], NULL) // pre-C++11

进行此更改后,我得到了正确的输出。


请注意,这不会处理错误情况,例如根本无法转换argv[i]。要检测这一点,您可以:

  • 将局部变量的地址作为第二个参数传递给strtod

    char *optr;
    double result = strtod(argv[i], &optr);
    // This checks if at least some part of the string has been converted
    // Check *optr != '' instead for whether the entire string is converted
    if(optr == argv[i]) { 
        // Handle failure...
    }
    
  • 使用 std::stod(适用于 C++11 或更高版本(,如果无法执行转换,则会引发std::invalid_argument异常。

相关文章: