Как я могу проверить, является ли число (двойной тип) сохраненный как строка допустимым двойным числом в C++?

У меня есть проблема с программой, я продолжаю работать в C++. Я прошу, чтобы пользователь ввел верный номер. Я принимаю его как строку, потому что особое присвоение, которое я делаю, это помогает в конечном счете. Для основной проверки ошибок я хочу проверить, чтобы видеть, является ли введенный номер верным номером. Пример:

Enter number: 3.14
This would be valid

Enter number: 3.1456.365.12
This shouldn't be valid
7
задан tshepang 15 May 2014 в 19:08
поделиться

11 ответов

Я думаю, что Boost :: Lexical_Cast должен помочь вам здесь

7
ответ дан 6 December 2019 в 06:14
поделиться

Используйте Strtod, который преобразует строку в двойную и возвращает любые символы, которые он не мог интерпретировать как часть двойного.

double strtod(const char* nptr, char** endptr)

Мне нравится:

char* input = "3.1456.365.12";
char* end;

strtod(input, &end);
if (*input == '\0')
{
  printf("fail due to empty string\n");
}
if (end == input || *end != '\0')
{
  printf("fail - the following characters are not part of a double\n%s\n", end);
}
9
ответ дан 6 December 2019 в 06:14
поделиться

Возможно, библиотека ASIHTTPRequest может помочь в этом?

-121--4518536-

Если у вас нет повышения, вы всегда можете использовать strtod

-121--3777345-

Ах, я любил эти задания. Старая добрая рука, написанная лексером, - это путь, по которому можно идти (так как вы все еще находитесь в первые дни - не пытайтесь использовать boost только что). Они быстрые, простые в написании и чрезвычайно весело играть. Если вы можете получить копию книги Ливайна о Lex/Yacc, найдите первые пару глав для идей.

0
ответ дан 6 December 2019 в 06:14
поделиться

Простая опция - использование функции sscanf:

const char * num_as_str = "3.1416";
double num;

if(std::sscanf(num_as_str, "%lg", &num) == 1)
{ 
    std::cout << "You correctly entered the number " << num << "\n";
} 

Если вы хотите получить фантазию, вы можете использовать istringstream:

std::istringstream iss(num_as_str);
if(iss >> num)
{
    std::cout << "You correctly entered the number " << num << "\n";
}

Если вы хотите получить экстра-фантазию, вы можете использовать lexical_cast:

try
{
    num = boost::lexical_cast<double>(num_as_str);
}
catch(boost::bad_lexical_cast &)
{ 
    std::cout << "What you entered is not a proper number" << num << "\n";
}
1
ответ дан 6 December 2019 в 06:14
поделиться

Это мой быстрый взлом :)

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

template <typename T>
bool fromStr(const std::string& str, T& var)
{
    std::stringstream convertor;
    convertor << str;
    convertor >> var;

    if( convertor.fail() )
        return false;

    char c = static_cast<char>( convertor.get() );

    return convertor.eof() || c == '\n' || c == ' ' || c == '\t';
}

int main()
{
    double d;
    std::string str = "5.04146.55";

    if( fromStr<double>(str, d) )
    {
        std::cout << "Valid conversion!, d = " << d;
    }
    else
    {
        std::cout << "Invalid conversion!";
    }   
}
0
ответ дан 6 December 2019 в 06:14
поделиться

Лучший способ - сделать фактическую попытку преобразовать вашу строку в Двойной , используя любой из стандартных и / или идиоматических способов выполнения преобразования и проверки ошибок потом Отказ В C, который будет функционируют из STRTO ... Группа (которые, конечно, отлично используются в C ++). В C ++ вы можете использовать преобразование на основе потока идиома.

Одним из них наблюдается, что общая конвенция в стандартных методах преобразования является преобразование «как можно больше», и не учитывает никаких дополнительных символов в качестве ошибки. Например, строка «123ABC» обычно считается действительным входом, причем только «123» часть преобразована. Все удобные методы предоставляют вам способ обнаружить тот факт, что после фактического номера есть что-то дополнительное, если вы хотите лечить эту ситуацию как ошибку. Но это зависит от вас, чтобы принять дополнительные шаги для выполнения этой проверки.

2
ответ дан 6 December 2019 в 06:14
поделиться

Если у вас нет повышения, вы всегда можете использовать Strtod

3
ответ дан 6 December 2019 в 06:14
поделиться

Пример использования только стандартной C++:

#include <sstream>

// ...

double dbl = 0.0;
std::istringstream num("3.1456.365.12");

num >> dbl;

if(!num.fail() &&
   num.eof()) // This second test is important! This makes sure that the entire string was converted to a number
{
    // success
}
else
{
    // failure
}

Версия бонусной общей шаблонной функции:

#include <sstream>
#include <string>
#include <exception>

// Version that throws an exception on a bad parse:

template <typename T>
T parse(const std::string& str)
{
    T value;
    std::istringstream parser(str);
    parser >> value;

    if(!parser.fail() && parser.eof())
    {
        return value;
    }
    else
    {
        throw "bad lexical cast";
    }
}

// usage:

double foo = parse<double>("3.14234");

// Non-exception, error code version

template <typename T>
bool parse(const std::string& str, T& value)
{
    std::istringstream parser(str);
    parser >> value;

    return (!parser.fail() && parser.eof());
}

// usage:

double foo = 0.0;
bool success = parser<double>("3.11234", foo);
4
ответ дан 6 December 2019 в 06:14
поделиться

Как упоминал Андрей Т, лучший способ - это попытаться преобразовать строку в плавающий диск и проверить на ошибку. Лично я бы предпочел использовать std::istringstream, так как вы используете C++. Должно сработать что-то вроде следующего:

float ff;
std::istringstream istr;
std::string input("1234.5678");

// set the stream to have your string as its base
istr.str(input);

// now try to read the number:
istr >> ff;
if (istr.fail())
{
    // some error in the parsing
}

istringstream является частью STL, так что дополнительные библиотеки вам не понадобятся, и будет с исключениями, если вы так решите. Дополнительную информацию можно найти здесь: http://www.cplusplus.com/reference/iostream/istringstream/

0
ответ дан 6 December 2019 в 06:14
поделиться

Можно использовать регулярные выражения. Так как у Вас уже есть строка, легко сравнить это с этим regex:

/^\d+(\.\d+)?$/

Библиотека regex.h может Вам помочь. Посмотрите на это: regex.h

0
ответ дан 6 December 2019 в 06:14
поделиться

Вы можете использовать STRTOX (где x - f f l l ul Для долгосрочных и т. Д.), Выбирая для того, что вы хотите. Один из параметров, которые вы даете, - это «конечный указатель», который указывает на первый символ в строке, которая может не , быть преобразован в тип целевого номера.

В вашем случае то, что вы, по-видимому, в том, что конечный указатель должен быть в конце строки, указывающую, что все символы в строке были преобразованы в тип целевого значения.

Править: Извините, не заметил, что вы упомянули «двойной» в названии (но не сам вопрос). Что касается случая, вы бы использовали Strtod , как также посоветовали пару других.

3
ответ дан 6 December 2019 в 06:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: