std::atoi()和std::stoi有什么区别?

60

atoi和stoi有什么区别?

我知道,

std::string my_string = "123456789";
为了将该字符串转换为整数,您需要执行以下操作:
const char* my_c_string = my_string.c_str(); 
int my_integer = atoi(my_c_string);

C++11 提供了一个简洁的替代方案:

std::string my_string = "123456789"; 
int my_integer = std::stoi(my_string);

1). 两者之间还有其他区别吗?

2). 在效率和性能方面,哪一个更好?

3). 哪一个使用起来更安全?


5
您可能想阅读例如 这个 std::stoi 参考文献 并将其与 这个 std::atoi 参考文献 进行比较。 - Some programmer dude
2
顺便提一下,std::atoi不是对应于std::stoi的C函数,相反,应该使用std::strtol,我建议使用strtol而不是atoi - Some programmer dude
你在 strtok 这一点上是正确的。 - Bhupesh Pant
1个回答

76

1). 这两者之间还有其他的区别吗?

我认为 std::atoi() 是一个糟糕的函数:它在出错时返回零。如果你把零看作是有效的输入,那么你不能确定转换过程中是否发生了错误还是输入确实是零。这很糟糕。例如,请查看如何判断 c 函数 atoi 是否失败或者是否是一串多个零?

另一方面,相应的 C++ 函数会在出错时抛出异常,你可以正确地区分输入的零和错误。

2). 在效率和性能方面,哪一个更好?

如果你不关心正确性,或者你确定不会有零作为输入,或者你把它看作是错误的输入,那么也许 C 函数可能会更快(可能是由于缺少异常处理)。这取决于您的编译器、标准库实现、硬件、输入等。最好的方法是进行测量。但是,我怀疑如果有任何差异,都是可以忽略不计的。

如果您需要一个快速(但丑陋的 C 风格)实现,这个如何在 C++ 中将字符串解析为整数?问题中最受欢迎的答案似乎是合理的。但是,除非绝对必要(主要由于要处理 char*\0 终止符),否则我不会使用该实现。

3). 哪一个更安全?

请参见第一点。

此外,如果您需要使用 char* 并注意 \0 终止符,则更容易犯错误。因为 std::string 会处理所有这些事情,所以它更易于使用和更安全。


3
这是非常实用的建议。关于你提到的第一点(返回值 vs 错误码),我查看了atoi函数的man页,上面写道:“它等价于:(int)strtol(str,(char )NULL,10);”,而从strtol函数的man页中可以看到,第二个参数的解释是:“(如果*first_param不是'\0'但second_param在返回时为'\0',则整个字符串是有效的。)”。因此,似乎使用带有第二个参数的strtol比atoi更好,以避免您在第1点中描述的问题。可以通过在代码中包含stdlib.h来使用strtol函数。 - Nick Desaulniers
@NickDesaulniers 是的,如果你查看我回答中链接的问题(“如何在C++中将字符串解析为整数?”),你会发现最受欢迎的答案也使用了 strtol。然而,除非我绝对必须这样做,否则我不会选择这条路;我不会使用 strtol,原因就是我在回答中提到的。 - Ali
@NickDesaulniers,顺便说一下,感谢您的评论:结果我的答案已经过时了。现在接受的答案不同,所以我的答案指的是错误的答案。 - Ali
@Ali “另一方面,相应的C++函数” - 您的意思是仅指不在std::命名空间中的atoi函数? - David Doria
@DavidDoria 我的意思是 std::stoi - Ali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接