将字符串转换为数字类型的通用方法

Generic way to convert a string into a numerical type?

本文关键字:方法 类型 数字 字符串 转换      更新时间:2023-10-16

我有这个类:

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;
};

现在,如果这个类不是泛型的,如果resultdouble,我会用这个方法来检测数字。

while((strchr("1234567890.",token))
{
     /* add token to a "temp" string */
     /* etc. etc. */
}
result = atof(temp.c_str());

但由于result是通用的,我不能使用任何像atofatoi等方法。

我该怎么办?

Boost内置了以下功能:
 #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月)。