strtod没有给出相同变量的一致结果?

时间:2014-09-11 17:06:27

标签: c++ string double

我正在学习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次)。

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

目前的完整文件(有很多调试功能)(抱歉,缩进很难,我也是第一次学习vim,而且在vim看起来很正确):http://paste.ubuntu.com/8320413 < / p>

1 个答案:

答案 0 :(得分:3)

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

I get the correct output我做了这个改变。


请注意,这不会处理错误情况,例如根本无法转换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 != '\0' instead for whether the entire string is converted
    if(optr == argv[i]) { 
        // Handle failure...
    }
    
  • 使用std::stod(对于C ++ 11或更高版本),如果无法执行转换,则会引发std::invalid_argument异常。