我正在学习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>
答案 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
异常。