C++ 确定字符串是否为双精度
我想看看字符串是否包含一个double作为其唯一内容。换句话说,如果它可能是以下函数的输出:C++ 确定字符串是否为双精度,c++,string,double,C++,String,Double,我想看看字符串是否包含一个double作为其唯一内容。换句话说,如果它可能是以下函数的输出: string doubleToString(double num) { stringstream s; s << num; return s.str(); } string doubleToString(双数值) { 细绳; 你想要这个函数 bool isOnlyDouble(const char* str) { char* endptr = 0;
string doubleToString(double num)
{
stringstream s;
s << num;
return s.str();
}
string doubleToString(双数值)
{
细绳;
你想要这个函数
bool isOnlyDouble(const char* str)
{
char* endptr = 0;
strtod(str, &endptr);
if(*endptr != '\0' || endptr == str)
return false;
return true;
}
您可以使用Boost检查字符串是否包含double
#include <boost/lexical_cast.hpp>
....
using boost::lexical_cast;
using boost::bad_lexical_cast;
....
template<typename T> bool isValid(const string& num) {
bool flag = true;
try {
T tmp = lexical_cast<T>(num);
}
catch (bad_lexical_cast &e) {
flag = false;
}
return flag;
}
int main(){
// ....
if (isValid<double>(str))
cout << "valid double." << endl;
else
cout << "NOT a valid double." << endl;
//....
}
#包括
....
使用boost::词法转换;
使用boost::bad_词法_cast;
....
模板布尔值有效(常量字符串和数值){
布尔标志=真;
试试{
T tmp=词汇投射(num);
}
捕捉(错误的词汇投射和e){
flag=false;
}
返回标志;
}
int main(){
// ....
if(isValid(str))
您可以选择C风格和boost风格,但在您的doubleToString
实现中:
bool is_double(const std::string& s)
{
std::istringstream iss(s);
double d;
return iss >> d >> std::ws && iss.eof();
}
这里,您正在检查iss>>d
返回iss
,如果流式处理成功,它将仅在布尔上下文中计算为true
。在eof()
之前只检查空格,以确保没有后续垃圾
如果您想考虑引导和尾随空白空间的垃圾:
return iss >> std::nowkipws >> d && iss.eof();
这可以概括为一个布尔返回测试,类似于boost的lexical\u cast
template <typename T>
bool is_ws(const std::string& s)
{
std::istringstream iss(s);
T x;
return iss >> x >> std::ws && iss.eof();
}
template <typename T>
bool is(const std::string& s)
{
std::istringstream iss(s);
T x;
return iss >> std::noskipws >> x && iss.eof();
}
...
if (is<double>("3.14E0")) ...
if (is<std::string>("hello world")) ...; // note: NOT a single string
// as streaming tokenises at
// whitespace by default...
模板
bool is_ws(const std::string&s)
{
标准:istringstream iss;
tx;
返回iss>>x>>std::ws&&iss.eof();
}
模板
bool is(const std::string&s)
{
标准:istringstream iss;
tx;
返回iss>>std::noskipws>>x&&iss.eof();
}
...
如果(是(“3.14E0”)。。。
if(is(“hello world”)…;//注意:没有一个字符串
//在
//默认为空白。。。
您可以将模板专门用于您想要的任何特定类型的行为,例如:
template <>
bool is<std::string>(const std::string& s)
{
return true;
}
模板
bool is(const std::string&s)
{
返回true;
}
或直接使用流:
#include <string>
#include <sstream>
#include <iostream>
template<typename T>
bool isValid(std::string const& num)
{
T value;
std::stringstream stream(num);
stream >> value;
// If the stream is already in the error state peak will not change it.
// Otherwise stream should be good and there should be no more data
// thus resulting in a peek returning an EOF
return (stream) &&
stream.peek() == std::char_traits<typename std::stringstream::char_type>::eof();
}
int main()
{
isValid<double>("55");
}
#包括
#包括
#包括
模板
bool是有效的(std::string const&num)
{
T值;
std::stringstream(num);
流>>值;
//如果流已经处于错误状态,peak将不会更改它。
//否则,流应该是好的,不应该有更多的数据
//从而导致偷看返回EOF
返回(流)&&
stream.peek()==std::char_traits::eof();
}
int main()
{
有效(“55”);
}
因为没有人提到它:显而易见的解决方案是,您想知道字符串是否具有给定的语法,就使用正则表达式。我不确定这是否是这种情况下的最佳解决方案,因为合法双精度的正则表达式相当复杂(因此很容易出错)。并且您的规范有点模糊:是否接受任何可以解析的字符串(例如通过>
)作为合法的双精度,或者只有字符串可以由doubleToString
函数返回?如果是前者,最简单的解决方案可能是将字符串转换为双精度,确保没有错误并且您已使用了所有字符(Martin的解决方案,只是在需要之前将其作为模板是愚蠢的)。如果是后者,最简单的解决方案是使用函数将找到的双精度值重新转换为字符串,并比较两个字符串。(只是为了明确区别:对于“1.0”
,“1E2”
,,.0000000000 1”
和“3.141592653589793238462643383279520288419716939937”
,您的函数将永远不会生成它。)如果不执行转换,则返回零,并且nptr的值存储在endptr引用的位置。如果(x)返回false,则我似乎无法使用这种检测双精度的方法;[else]return true;
更好地表达为'return!(x);Chris:它可以更好地考虑代码:删除冗余的“return”",关键字true
和false
显然是任何逻辑测试的结果,以及if
语句也隐含在这种情况下。因此,这证明它更简洁。我无法证明它本身更简单或更好-这取决于程序员维护它。尽管如此,经过28年的编程我可以向你保证,业界的期望和最佳实践是,程序员应该尽一点努力,让他们的头脑了解布尔运算的本质,并相应地简化代码。根据strdot的文档,小数点依赖于本地。因此,这意味着此函数旨在从m用户输入,但不适合解析某些定义良好的格式,例如文件。假设您使用点作为小数点,但在捷克Windows上是逗号默认小数点而不是点。因此,strdot将查找逗号,它是美国格式的千位分隔符。您将解析非小数点和完全不同的数字d、 @BoundaryImposition:return endptr!=str&&&*endptr=='\0';
不是以牺牲复杂性为代价进行压缩的-它是简化的。如果你在Chris的回答中比If
语句更纠结于这一点,那么你就不应该专业地编程。-1用于滥用异常。异常不应该用于控制流,克里斯:我有,但不足以采用Python风格。即使如此,一种语言中的正常语言在另一种语言中是很差的。另一个例子是在使用列表理解时,在OCAML中编写C++代码。@ Ben Voigt:我认为代码比代码片段更完美和更干净。Chris发布。lexical_cast(num);
在失败时抛出异常。我想不出更好的替代方法。@Chris:但实际上,它捕获异常以将其转换为返回值,这是