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