确定字符串是否为双精度值

Determining if a string is a double

本文关键字:双精度 是否 字符串      更新时间:2023-10-16

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

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

你想要 strtod 函数。

bool isOnlyDouble(const char* str)
{
    char* endptr = 0;
    strtod(str, &endptr);
    if(*endptr != '' || endptr == str)
        return false;
    return true;
}
您可以使用

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;
  //....
}

你已经得到了 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;
}

或者直接使用流:

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

我做了一个可能会有帮助的函数?它还检查 12.3.4 或 1,4 等拼写错误。

// check if input string is decimal
bool is_decimal_str(string input)
{
    int decimal = 0;
    int index = 0;
    for (auto character : input)
    {
        if (character == '.')
        {
            decimal++;
        }
        else if ((character == '+' || character == '-') && index == 0);
        else if (!isdigit(character))
        {
            return false;
        }
        if (decimal > 1)
        {
            return false;
        }
        index++;
    }
    return true;
}

   // check if input string is decimal
    bool is_decimal_str(string input)
    {
        int decimal = 0;
        for (int index = 0; index < input.size(); index++)
        {
            if (input[index] == '.')
            {
                decimal++;
            }
            else if ((input[index] == '+' || input[index] == '-') && index == 0);
            else if (!isdigit(input[index]))
            {
                return false;
            }
    
            if (decimal > 1)
            {
                return false;
            }
        }
        return true;
    }

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