分析std::string中的整数,但如果为float,则会失败 在C++和C中,有多种方法将字符串转换成整数,但是我没有发现在解析浮点数时失败的转换方法。 const float fnum = std::stof("1.5"); std::cout << fnum << std::endl; // prints "1.5", all okay const int inum = std::stoi("1.5"); std::cout << inum << std::endl; // prints "1", but wrong! const float fnum=std::stof(“1.5”); std::cout
对于包含十进制数的数字,您希望失败。您可以测试点,也可以测试十进制数字分析std::string中的整数,但如果为float,则会失败 在C++和C中,有多种方法将字符串转换成整数,但是我没有发现在解析浮点数时失败的转换方法。 const float fnum = std::stof("1.5"); std::cout << fnum << std::endl; // prints "1.5", all okay const int inum = std::stoi("1.5"); std::cout << inum << std::endl; // prints "1", but wrong! const float fnum=std::stof(“1.5”); std::cout,c++,c++11,C++,C++11,对于包含十进制数的数字,您希望失败。您可以测试点,也可以测试十进制数字 if (num.find('.') != string::npos || num.find(',') != string::npos) cout << "Number is not integer" << endl; if(num.find(‘.)!=string::npos | | num.find(‘,’)!=string::npos) cout您可以使用boost词法转换。如果强制转换失
if (num.find('.') != string::npos || num.find(',') != string::npos)
cout << "Number is not integer" << endl;
if(num.find(‘.)!=string::npos | | num.find(‘,’)!=string::npos)
cout您可以使用boost词法转换。如果强制转换失败,它将抛出异常
try
{
number = boost::lexical_cast<int>(your_string);
}
catch (const boost::bad_lexical_cast& exec)
{
// do something on fail
}
试试看
{
number=boost::词法转换(您的字符串);
}
捕获(const boost::bad\u词法\u cast&exec)
{
//失败时做某事
}
您应该反复检查数字是否解析为1)整数,2)浮点数,最后3)两者都不是。但是“解析”应该意味着整个字符串被使用
试着这样做:
#include <sstream>
#include <string>
bool TryAsInt(const std::string & s, long long int & out)
{
std::istringstream iss(s);
return (iss >> out >> std::ws) && (iss.get() == EOF);
}
然后,您仍然必须将其与检查所有字段的逻辑相结合
例如:
#include <cerrno>
#include <cstdlib>
#include <string>
bool TryAsInt(const std::string & s, long long int & out)
{
char * e;
errno = 0;
out = std::strtoll(s.data(), &e, 0);
return errno == 0 && s.data() + s.size() == e;
}
std::vector<string> raw_fields;
long long int n;
double x;
if (std::all_of(raw_fields.begin(), raw_fields.end(),
[&n](const string & s) { return TryAsInt(s, n); })
{
// integer case
}
else if (std::all_of(raw_fields.begin(), raw_fields.end(),
[&x](const string & s) { return TryAsFloat(s, x); })
{
// floating point case
}
else
{
// just use raw_fields as-is
}
std::向量原始字段;
长整型n;
双x;
if(std::all_of(raw_fields.begin(),raw_fields.end(),
[&n](常量字符串&s){return TryAsInt(s,n);}
{
//整型
}
else if(std::all_of(raw_fields.begin()、raw_fields.end()),
[&x](常量字符串&s){return TryAsFloat(s,x);}
{
//浮点型
}
其他的
{
//只需按原样使用原始字段
}
如果需要更多类型检查,请查看boost。
例如,您可以执行以下操作:
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <string>
template<typename T, typename RuleType>
bool is_type(std::string const& str, RuleType const& rule, T& val)
{
using namespace boost::spirit::x3;
auto beg = std::begin(str);
auto end = std::end(str);
auto ret = parse(beg,end, rule, val);
return ret && (beg==end);
}
int main(int argc, char** argv)
{
std::string s1="1.0";
float v;
std::cout << s1 << " is int ? : " << is_type(s1, boost::spirit::x3::int_, v) << "\n";
std::cout << s1 << " is float ? : " << is_type(s1, boost::spirit::x3::float_, v) << "\n";
return 0;
}
#包括
#包括
#包括
模板
bool是_类型(std::string const&str、RuleType const&rule、T&val)
{
使用名称空间boost::spirit::x3;
自动beg=std::begin(str);
自动结束=标准::结束(str);
自动返回=解析(beg、end、rule、val);
返回ret&(beg==结束);
}
int main(int argc,字符**argv)
{
std::string s1=“1.0”;
浮动v;
std::cout对其使用普通std::stoi,但一定要检查字符串是否已完全使用。例如:
static bool isIntValue(const std::string& string, int32_t& intValue)
{
try
{
size_t lastChar;
intValue = std::stoi(string, &lastChar);
return lastChar == string.size();
}
catch (...)
{
return false;
}
}
此代码的执行速度比std::istringstream解决方案快得多。还有另一个参数,可以像strtol
的end参数一样使用。如果您觉得它“难看”那么搜索字符串以确定字符是否正确如何?@dommynik-您确定const int fnum
?不是const float fnum
?除了Joachim所说的之外,您还可以使用stringstream
,并在转换调用后检查流是否为空。没有真正好的方法。无论哪种方法a)对于字符串解析。或b)使用boost的词法转换(这应该抛出异常,这有点难看)或者c)之后将其转换回字符串,看看字符串是否相同。啊,是的,stringstreams。@max66谢谢,抱歉,更改了!如果int是32位的,并且也是float,则float不能准确表示所有的int值。是的,我刚刚意识到float只能表示24位的整数。谢谢
不是唯一可以这样做的字符请使用浮点文本,但不要使用整数。您也需要排除e
和e
。谢谢,我会尝试一下-但我必须运行一些比较boost、stringstreams和stoi的计时基准。@dommynik:如果您需要性能,那么对输入执行原始词法分析会更有效。@r这比所有的冗余解析都要好。这不是很简单,但是可行。这些结果看起来很有希望,谢谢!
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <string>
template<typename T, typename RuleType>
bool is_type(std::string const& str, RuleType const& rule, T& val)
{
using namespace boost::spirit::x3;
auto beg = std::begin(str);
auto end = std::end(str);
auto ret = parse(beg,end, rule, val);
return ret && (beg==end);
}
int main(int argc, char** argv)
{
std::string s1="1.0";
float v;
std::cout << s1 << " is int ? : " << is_type(s1, boost::spirit::x3::int_, v) << "\n";
std::cout << s1 << " is float ? : " << is_type(s1, boost::spirit::x3::float_, v) << "\n";
return 0;
}
static bool isIntValue(const std::string& string, int32_t& intValue)
{
try
{
size_t lastChar;
intValue = std::stoi(string, &lastChar);
return lastChar == string.size();
}
catch (...)
{
return false;
}
}