Как я проверяю, является ли строка C++ интервалом?

Когда я использую getline, Я ввел бы набор строк или чисел, но я только хочу, чтобы цикл с условием продолжения произвел "слово", если это не число. Так есть ли какой-либо способ проверить, является ли "слово" числом или нет? Я знаю, что мог использовать atoi() для струн до, но как насчет для строк строкового класса?

int main () {
  stringstream ss (stringstream::in | stringstream::out);
  string word;
  string str;
  getline(cin,str);
  ss<<str;
  while(ss>>word)
    {
      //if(    )
        cout<<word<<endl;
    }
}
37
задан Peter Mortensen 3 June 2010 в 10:20
поделиться

6 ответов

Другая версия...

Используйте strtol, обернув его внутри простой функции, чтобы скрыть его сложность :

inline bool isInteger(const std::string & s)
{
   if(s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false;

   char * p;
   strtol(s.c_str(), &p, 10);

   return (*p == 0);
}

Почему strtol ?

Насколько я люблю C++, иногда API C является лучшим ответом, насколько я понимаю:

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

Как это работает?

strtol на первый взгляд кажется довольно грубым, поэтому объяснение упростит чтение кода:

strtol разберет строку, остановившись на первом символе, который нельзя считать частью целого числа. Если указать p (как я сделал выше), он установит p прямо на этот первый нецелый символ.

Я рассуждаю так: если p не установлен в конец строки (символ 0), то в строке s есть нецелый символ, а значит s не является правильным целым числом.

Первые тесты служат для исключения угловых случаев (пробелы, пустая строка и т.д.).

Разумеется, эта функция должна быть адаптирована под ваши нужды (являются ли пробелы ошибкой? и т.д.).

Источники :

См. описание strtol на: http://en.cppreference.com/w/cpp/string/byte/strtol.

См. также описание родственных функций strtol (strtod, strtoul и т.д.).

66
ответ дан 27 November 2019 в 04:01
поделиться

Если вы просто проверяете, слово - это число, это не слишком сложно:

#include <ctype.h>

...

string word;
bool isNumber = true;
for(string::const_iterator k = word.begin(); k != word.end(); ++k)
    isNumber &&= isdigit(*k);

Оптимизируйте по желанию.

8
ответ дан 27 November 2019 в 04:01
поделиться

Вы можете попробовать boost :: lexical_cast . В случае неудачи он генерирует исключение bad_lexical_cast .

В вашем случае:

int number;
try
{
  number = boost::lexical_cast<int>(word);
}
catch(boost::bad_lexical_cast& e)
{
  std::cout << word << "isn't a number" << std::endl;
}
15
ответ дан 27 November 2019 в 04:01
поделиться

Вы можете использовать boost :: lexical_cast , как предлагается, но если у вас есть какие-либо предварительные знания о строках (т. Е. Если string содержит целочисленный литерал, у которого не будет начального пробела или что целые числа никогда не записываются с показателями), то прокрутка вашей собственной функции должна быть более эффективной и не особенно сложной.

3
ответ дан 27 November 2019 в 04:01
поделиться
template <typename T>
const T to(const string& sval)
{
        T val;
        stringstream ss;
        ss << sval;
        ss >> val;
        if(ss.fail())
                throw runtime_error((string)typeid(T).name() + " type wanted: " + sval);
        return val;
}

А затем вы можете использовать это так:

double d = to<double>("4.3");

или

int i = to<int>("4123");
1
ответ дан 27 November 2019 в 04:01
поделиться

Итак, как я понимаю, у вас есть 3 варианта.

1: Если вы просто хотите проверить, является ли число целым, и не заботитесь о его преобразовании, а просто хотите сохранить его как строку и не заботитесь о потенциальных переполнениях, то проверка соответствия regex для целого числа будет идеальным вариантом.

2: Вы можете использовать boost::lexical_cast и затем поймать потенциальное исключение boost::bad_lexical_cast, чтобы узнать, не произошло ли преобразование. Это будет хорошо работать, если вы можете использовать boost и если неудача преобразования является исключительным условием.

3: Создайте собственную функцию, аналогичную lexical_cast, которая проверяет преобразование и возвращает true/false в зависимости от того, успешно оно или нет. Это будет работать в случае, если 1 и 2 не подходят под ваши требования.

3
ответ дан 27 November 2019 в 04:01
поделиться
Другие вопросы по тегам:

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