Как определить, есть ли в строке не числа? - PullRequest
0 голосов
/ 25 апреля 2011

Я делаю класс с именем Double, который может преобразовывать строки в двойные и двойные в строковые.Мне нужен какой-то способ проверить, чтобы, когда пользователь вводит строку, в строке не было ничего, кроме числа.Некоторая функция bool, которая возвращает false, если строка состоит из всех чисел, и true, если в ней есть не числа.Пока что у меня есть

string test;
double d;

cout << "Enter a string: ";
cin >> test;

if(isNAN(test)) //isNAN (is Not A Number)
    cout << "Your entry cannot be converted";
else
{
    Double d1(test); //overloaded constructor takes a string
    cout << "Your string as a double is: " << d1.toDouble() << "\n\n";
}

Я думал сделать цикл для запуска через строку и протестировать каждый символ, но это кажется большой работой.Есть ли какая-то простая функция, которая может определить, является ли какая-либо часть строки не числом?

Кроме того, я конвертирую ее, используя strstream, примерно так:Будет ли проще проверить не числа, если я сначала преобразую его?

Ответы [ 4 ]

3 голосов
/ 25 апреля 2011

Звучит так, как будто вы хотите убедиться, что вся строка преобразуется в double, т. Е. После преобразования не осталось ввода. Простой способ убедиться в этом: eof():

std::istringstream ss( str.c_str() );
ss >> d;

// ss >> std::ws; if you want to ignore trailing whitespace

if ( ss && ss.eof() ) {
    return d; // successful conversion
} else {
    // input left over
}

Для ленивых это можно записать в виде одной строки:

double d;
if ( ( istringstream( str.c_str() ) >> d >> ws ).rdstate() == ios::eofbit ) {
2 голосов
/ 25 апреля 2011

Для правильной проверки ошибок, вы можете проверить результат из ss >> d:

if (!(ss >> d))
{
    // conversion was unsuccessful...
}

Подробное обсуждение и полный / общий код преобразования см. В

http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2

Было бы проще проверить не числа, если я сначала его преобразовал?

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

Что касается , где для помещения кода преобразования, то это вопрос баланса между дизайном чистого класса и ожидаемым использованием кода. Если конструктор вызывается много, и у большинства пользователей есть строка (а не двойная), то вы можете подумать о том, чтобы испачкать класс и поместить код преобразования в альтернативный конструктор. В противном случае позвольте классу беспокоиться о том, для чего он был разработан, и отделите код преобразования от класса. См:

1 голос
/ 25 апреля 2011

Использовать strtod .Эта функция преобразует строку (в стиле C) в двойную для вас и сообщит вам, какая часть строки была использована при преобразовании (поэтому вы можете проверить, чтобы вся строка была действительным числом и была проанализирована).

Бонус в том, что это, вероятно, быстрее, чем использование потоков (попробуйте!).

0 голосов
/ 25 апреля 2011

Я бы использовал что-то простое и проверенное временем:

bool str2f(const char* str, double& d)
{
  return sscanf(str,"%e", &d) == 1;
}

Это даст вам true в случае успеха и само значение.

...