将字符串转换为数字类型的通用方法
Generic way to convert a string into a numerical type?
我有这个类:
template<typename T> class Parser
{
public:
Parser() : count(0) {}
virtual void parse(const string&);
void get_token(void);
private:
T result;
char token;
string expression;
int count;
};
现在,如果这个类不是泛型的,如果result
是double
,我会用这个方法来检测数字。
while((strchr("1234567890.",token))
{
/* add token to a "temp" string */
/* etc. etc. */
}
result = atof(temp.c_str());
但由于result
是通用的,我不能使用任何像atof
和atoi
等方法。
我该怎么办?
#include <boost/lexical_cast.hpp>
void Parser<T>::get_token() {
std::string token = ...;
result = boost::lexical_cast<T>(token);
}
根据需要添加异常处理。
或者,也许你出于某种原因不想使用Boost:
void Parser<T>::get_token() {
std::string token = ...;
std::stringstream ss;
ss << token;
ss >> result;
}
根据需要检查ss
的错误状态。
在这个相关的问题上可能会找到更广泛的答案,尽管它只具体讨论了int
。
另一个基于通用模板的数字到字符串转换器。需要int
s和double
s。
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
template <class T>
inline std::string Numeric_To_String (const T& t)
{
std::stringstream ss;
ss << t;
return ss.str();
}
int main(int argc, char *argv[])
{
int i = 9;
double d = 1.2345;
string s;
cout <<"Generic Numeric_To_String( anyDatatype ) nn";
s = Numeric_To_String( i );
cout <<"int i to string : "<< s <<" "<< endl;
s = Numeric_To_String( d );
cout <<"double d to string : "<< s <<" "<< endl;
cout <<" n";
return 0;
}
如果你只有一手想要解析的类型,你可以使用模板专业化:
template<>
void Parser<int>::parse(const string&)
{
result = atoi(string.c_str());
}
template<>
void Parser<float>::parse(const string&)
{
result = atof(string.c_str());
}
当然,只有当您实现了所需的每一个转换时,这才有效。
使用C++17,您可以使用模板化的std::from_chars
。https://en.cppreference.com/w/cpp/utility/from_chars
#include <charconv>
#include <iostream>
template <typename Number>
auto stringTo(std::string_view str)
{
Number number;
std::from_chars(str.data(), str.data() + str.size(), number);
return number;
}
int main()
{
const auto str = std::string("42");
std::cout << stringTo<long>(str) << 'n';
std::cout << stringTo<double>(str) << 'n';
}
检查std::from_chars
的返回值以检测错误。
const auto result = std::from_chars(...);
if (result.ec == std::errc::invalid_argument || result.ec == std::errc::result_out_of_range)
{
std::cout << "string to number error" << 'n';
}
更多信息和示例:https://www.bfilipek.com/2018/12/fromchars.html
GCC和clang还不支持std::from_chars
的浮点版本(2019年8月)。
相关文章:
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 是否有内置方法可以强制转换为不同的基础类型,但保留常量限定符?
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 类作用域的类型别名"using":[何时]方法中的用法可以先于类型别名?
- 调用具有未标识类型的类的方法
- 将复杂的非基元C++数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法
- 我的模板类方法返回错误类型?
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- QtQuick - qml:28:错误:未知方法返回类型:自定义类型
- 构造智能点数据类型以及普通数据类型的通用方法
- 如何在没有实例的情况下获取非静态方法的类型?
- C++方法是否可以根据传递给构造函数的参数具有不同的返回类型?
- 在自定义 std::vector-like 容器中处理指针和非指针模板类型的最佳方法是什么?
- 使用类型id运算符的最佳替代方法
- 检查子类型时的专用方法模板
- C ++类型特征:确保子类实现方法
- 标识派生类类型的正确方法(类型实体VS dynamic_case)
- 类方法类型的decltype