Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将字符串转换为数字类型的通用方法?_C++_String_Generics_Types_Casting - Fatal编程技术网

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

C++ 将字符串转换为数字类型的通用方法?,c++,string,generics,types,casting,C++,String,Generics,Types,Casting,我有这门课: 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;

我有这门课:

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
是通用的,我不能使用像
atof
atoi
等任何方法


我该怎么办?

Boost内置了以下功能:

 #include <boost/lexical_cast.hpp>

 void Parser<T>::get_token() {
     std::string token = ...;
     result = boost::lexical_cast<T>(token);
 }
#包括
void解析器::get_token(){
字符串标记=。。。;
结果=boost::词法转换(令牌);
}
根据需要添加异常处理


或者,您可能出于某种原因不想使用Boost:

void Parser<T>::get_token() {
     std::string token = ...;

     std::stringstream ss;
     ss << token;
     ss >> result;
}
void解析器::获取令牌(){
字符串标记=。。。;
std::stringstream-ss;
ss>结果;
}
根据需要检查
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 ) \n\n";

  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;
}
#包括
#包括
#包括
使用名称空间std;
模板
内联标准::字符串数字到字符串(常量T&T)
{
std::stringstream-ss;

ss如果您只有一手想要解析的类型,那么可以使用模板专门化:

template<>
void Parser<int>::parse(const string&)
{
    result = atoi(string.c_str());
}

template<>
void Parser<float>::parse(const string&)
{
    result = atof(string.c_str());
}
模板
void Parser::parse(常量字符串&)
{
结果=atoi(string.c_str());
}
模板
void Parser::parse(常量字符串&)
{
结果=atof(string.c_str());
}
。。。
当然,这只有在您实现所需的每个转换时才有效。

使用C++17,您可以使用模板化的
std::from_chars

更多信息和示例:


GCC和clang还不支持来自_chars的std::的浮点版本(2019年8月).

·你可以使用
std::istringstream
。或者你可以使用
boost::lexical\u cast
,它在内部使用流。干杯,谢谢,@Xeo:now.Related,不过。@Lightness:是的,在重读之后,我注意到它漏掉了“generic”部分。+ 1,谢谢。我宁愿不增加我的项目,所以我将与<代码> StrugStudio @ MealTeaHeaHea:你只需要一个页眉。就是这样。<代码> Booost 解决方案更加健壮。请再次考虑。(如果你正在编写解析器,我很困惑你已经不使用Boost了!)@MediateHacker:在编写解析器时,我会求助于解析器生成器。Boost.Spirit在这方面非常棒。@Xeo是的,如果我愿意,我会这样做,为严肃的工作构建一个解析器,比如专业的编程语言/脚本等。但我实际上正在尝试学习递归下降解析器等是如何实现的。T因此,我认为,从头开始写将教会我更多。关于
atoi
atof
-。还需要使用命名参数;
string.c_str()
不起作用。
template<>
void Parser<int>::parse(const string&)
{
    result = atoi(string.c_str());
}

template<>
void Parser<float>::parse(const string&)
{
    result = atof(string.c_str());
}
#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'; 
}
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';
}