确定字符串是否为double

wro*_*ame 10 c++ string double

我想看看一个字符串是否包含double作为其唯一内容.换句话说,如果它可能是以下函数的输出:

string doubleToString(double num)
{
    stringstream s;
    s << num;
    return s.str();
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*rle 11

你想要strtod功能.

bool isOnlyDouble(const char* str)
{
    char* endptr = 0;
    strtod(str, &endptr);

    if(*endptr != '\0' || endptr == str)
        return false;
    return true;
}
Run Code Online (Sandbox Code Playgroud)

  • `if(x)返回false; [else] return true;`更好地表达为`return!(x); (4认同)
  • 克里斯:它更好地考虑了代码:删除了一个**冗余**"return",关键字"true"和"false"显然是任何逻辑测试的结果,以及隐含的"if"语句情况.所以,这证明它更简洁.我无法证明它本身更简单或更好 - 这取决于程序员维护它.尽管如此,经过28年的编程,我可以向您保证业界的期望和最佳实践是,程序员应该尽量小心地了解布尔值的本质,并相应地简化代码. (4认同)
  • 根据strdot的文档,小数点是局部相关的。因此,这意味着该函数旨在解析用户输入中的十进制数字,但不适用于解析某些定义明确的格式,例如文件。假设您将点用作小数点,但是在捷克语Windows中,逗号是默认的小数点而不是点。因此strdot将寻找逗号,即美国格式的千位分隔符。您将解析非十进制和完全不同的数字。 (2认同)
  • @BoundaryImposition:`return endptr != str &amp;&amp; *endptr == '\0';` 不会以牺牲复杂性为代价进行压缩 - 它被简化了。如果您比 Chris 回答中的“if”语句更难解决这个问题,那么您不应该进行专业编程。 (2认同)

Pra*_*rav 6

您可以使用Boost lexical_cast来检查字符串是否包含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;
  //....
}
Run Code Online (Sandbox Code Playgroud)

  • -1滥用例外.不应将例外用于控制流程,仅用于处理特殊情况. (3认同)
  • @Ben Voigt:我认为代码完全不错,比Chris发布的代码片段更清晰.`lexical_cast的<T>(NUM); `在失败时抛出异常.我想不出更好的选择. (2认同)

Ton*_*roy 5

您已经获得了C风格和提升替代方案,但是以您的doubleToString实施方式:

bool is_double(const std::string& s)
{
    std::istringstream iss(s);
    double d;
    return iss >> d >> std::ws && iss.eof();
}
Run Code Online (Sandbox Code Playgroud)

在这里,您正在检查iss >> d返回iss,true如果流式传输成功,它将仅在布尔上下文中求值.除了空格之外什么都没检查eof()确保没有尾随垃圾.

如果你想考虑前导和尾随空白垃圾:

    return iss >> std::nowkipws >> d && iss.eof();
Run Code Online (Sandbox Code Playgroud)

这可以推广到类似于boost的布尔返回测试lexical_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...
Run Code Online (Sandbox Code Playgroud)

您可以针对任何类型特定的行为专门化模板,例如:

template <>
bool is<std::string>(const std::string& s)
{
    return true;
}
Run Code Online (Sandbox Code Playgroud)