有关具体示例,请考虑atoi(const std::string &)
.这非常令人沮丧,因为我们作为程序员需要使用它.
更一般的问题是为什么C++标准库没有用C++字符串,C++向量或其他C++标准元素重新实现标准C库而不是保留旧的C标准库并迫使我们使用旧的char *
接口?
它耗时并且在这两个接口之间转换数据类型的代码并不容易优雅.
这是为了兼容的原因,考虑到比现在有更多的遗留C代码,保留这些C标准接口会使从C代码到C++的转换更容易吗?
另外,我听说过许多其他可用于C++的库对STL进行了大量的增强和扩展.那么库是否支持这些功能呢?
PS:考虑到第一个具体问题的更多答案,我编辑了很多来澄清问题,以概述我更加好奇的问题.
jal*_*alf 14
另一个更普遍的问题是为什么STL不重新实现所有标准C库
因为旧的C库可以解决问题.如果C++标准库能够比旧版本更好地执行它,则它只重新实现现有功能.对于C库的某些部分来说,编写新的C++实现的好处并不足以证明额外的标准化工作是正确的.
至于atoi
等等,在类中的C++标准库中有这些的新版本std::stringstream
.
要从类型T转换为类型U:
T in;
U out;
std::stringstream sstr(in);
sstr >> out;
Run Code Online (Sandbox Code Playgroud)
与IOStream库的其余部分一样,它并不完美,它非常冗长,速度非常慢,等等,但它确实有效,而且通常它足够好.它可以处理所有大小的整数,浮点值,C和C++字符串以及定义运算符<<的任何其他对象.
编辑:此外,我听说许多其他可用于C++的库对STL进行了大量的增强和扩展.那么库是否支持这些功能?
Boost有一个boost::lexical_cast
包装std::stringstream
.使用该功能,您可以将上面的内容写成:
U out = boost::lexical_cast<U>(in);
Run Code Online (Sandbox Code Playgroud)
即使在C语言中,使用atoi
对于转换用户输入也不是一件好事.它根本不提供错误检查.提供它的C++版本并不是那么有用 - 考虑到它不会抛出任何东西,你可以传递.c_str()
给它并使用它.
相反,你应该使用strtol
C代码,它确实进行错误检查.在C++ 03中,你可以使用stringstreams来做同样的事情,但是它们的使用容易出错:你究竟需要检查什么?.bad()
,.fail()
或.eof()
?你怎么吃剩余的空白?格式化标志怎么样?这样的问题不应该打扰普通用户,只想转换他的字符串.boost::lexical_cast
确实做得很好,但顺便说一下,C++ 0x添加了实用程序函数,以便通过C++包装器来实现快速安全的转换,如果转换失败则可以抛出:
Run Code Online (Sandbox Code Playgroud)int stoi(const string& str, size_t *idx = 0, int base = 10); long stol(const string& str, size_t *idx = 0, int base = 10); unsigned long stoul(const string& str, size_t *idx = 0, int base = 10); long long stoll(const string& str, size_t *idx = 0, int base = 10); unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10);
效果:在第一个两个函数调用
strtol(str.c_str(), ptr, base)
,而最后三个函数调用strtoul(str.c_str(), ptr, base)
,strtoll(str.c_str(), ptr, base)
和strtoull(str.c_str(), ptr, base)
分别.每个函数返回转换后的结果(如果有).该参数ptr
指定一个指向函数内部对象的指针,该对象用于确定要存储的内容*idx
.如果函数没有抛出异常idx != 0
,则函数存储在*idx
str的第一个未转换元素的索引中.返回:转换后的结果.
抛出:
invalid_argument
如果strtol
,strtoul
,strtoll
,或者strtoull
没有转换可以进行报告.out_of_range
如果转换后的值超出返回类型的可表示值范围,则抛出此异常.
没有好办法知道atoi是否失败.它总是返回一个整数.该整数是有效转换吗?或者是0或-1或其他表示错误的?是的,它可能会抛出异常,但这会改变原始合同,并且您必须更新所有代码以捕获异常(这是OP所抱怨的).
如果翻译太耗费时间,请编写自己的atoi:
int atoi(const std::string& str)
{
std::istringstream stream(str);
int ret = 0;
stream >> ret;
return ret;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2469 次 |
最近记录: |