确定字符串是否为double

时间:2011-05-09 04:08:03

标签: c++ string double

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

string doubleToString(double num)
{
    stringstream s;
    s << num;
    return s.str();
}

5 个答案:

答案 0 :(得分:11)

您需要strtod功能。

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

    if(*endptr != '\0' || endptr == str)
        return false;
    return true;
}

答案 1 :(得分: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;
  //....
}

答案 2 :(得分:5)

您已获得C风格和提升替代方案,但采用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_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...

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

template <>
bool is<std::string>(const std::string& s)
{
    return true;
}

答案 3 :(得分:2)

或直接使用流:

#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");
}

答案 4 :(得分:-1)

由于没有其他人提到它:显而易见的解决方案是你想知道字符串是否具有给定的语法是使用正则表达式。在这种情况下,我不确定它是最好的解决方案,因为合法双精度的正则表达式相当复杂(因此很容易出错)。并且您的规范有些模糊:您是否希望接受任何可以解析的字符串(例如>>)作为合法双重字符串,或者只有字符串可以由doubleToString函数返回?如果是前者,最简单的解决方案可能是将字符串转换为double,确保没有错误,并且已经消耗了所有字符(Martin的解决方案,除非在您需要之前使其成为模板是愚蠢的) 。如果是后者,最简单的解决方案是使用您的函数将您发现的双重转换回字符串,并比较两个字符串。 (只是为了明确区别:Martin的函数将返回true "&nbsp;&nbsp;1.0""1E2"".00000000001""3.14159265358979323846264338327950288419716939937"等函数,您的函数永远不会生成。)