Я хотел бы видеть, содержит ли строка двойное значение в качестве единственного содержимого. Другими словами, если это может быть выход следующей функции:
string doubleToString(double num)
{
stringstream s;
s << num;
return s.str();
}
Я хотел бы видеть, содержит ли строка двойное значение в качестве единственного содержимого. Другими словами, если это может быть выход следующей функции:
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 != '\0' || 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-style и 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_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");
}
Так как никто другой не упомянул об этом: очевидное решение - вы хотите знать, является ли строка заданным синтаксисом для использования регулярных выражений. Я не уверен, что это лучшее решение в этом случае, поскольку регулярное выражение для легального двойника довольно сложно (и, следовательно, легко ошибиться). И ваша спецификация несколько неопределенная: хотите ли вы принять любую строку, которая может быть проанализирована (например, >>
) в качестве юридического двойника, или только ваши функции могут быть возвращены вашей функцией doubleToString
? Если первое, самое простое решение, вероятно, состоит в том, чтобы преобразовать строку в double, убедившись, что нет ошибки, и вы использовали все символы (решение Мартина, за исключением того, что это глупо, чтобы сделать его шаблоном, пока вам не понадобится), Если последнее, самое простое решение состоит в том, чтобы повторно преобразовать двойной, который вы вернули в строку, используя вашу функцию и сравнить две строки. (Просто для того, чтобы понять разницу: функция Martin вернет true
для таких вещей, как " 1.0"
, "1E2"
, ".00000000001"
и "3.14159265358979323846264338327950288419716939937"
, которые ваша функция никогда не будет генерировать.)