Могу ли я сказать, представляет ли std :: string число с использованием stringstream? - PullRequest
8 голосов
/ 07 февраля 2011

Очевидно, это подходит для показа, является ли строка числовой, например, "12.5" == да, "abc" == нет.Тем не менее я получаю нет, независимо от ввода.

std::stringstream ss("2");
double d; ss >> d;
if(ss.good()) {std::cout<<"number"<<std::endl;}
else {std::cout<<"other"<<std::endl;}

Ответы [ 4 ]

7 голосов
/ 07 февраля 2011

Не используйте хороший ()!Проверьте, является ли поток неудачным или нет :

if (ss)

Good сообщает вам, установлены ли какие-либо из eofbit, badbit или failbit, а fail () сообщает вам о badbit и failbit.Вы почти никогда не заботитесь о eofbit, если вы уже не знаете, что поток не работает, поэтому вы почти никогда не хотите использовать good.

Обратите внимание, что тестирование потока напрямую, как указано выше, в точности эквивалентно:

if (!ss.fail())

И наоборот,! Ss эквивалентно ss.fail ().


Объединение извлечения в условное выражение:

if (ss >> d) {/*...*/}

Isв точности эквивалентно:

ss >> d;
if (ss) {/*...*/}

Однако вы, вероятно, захотите проверить, может ли полная строка быть преобразована в double, что немного сложнее.Используйте boost :: lexical_cast, который уже обрабатывает все случаи.

6 голосов
/ 15 февраля 2013

Если вы хотите проверить, содержит ли string только число и ничего больше (кроме пробелов), используйте это:

#include <sstream>

bool is_numeric (const std::string& str) {
    std::istringstream ss(str);
    double dbl;
    ss >> dbl;      // try to read the number
    ss >> std::ws;  // eat whitespace after number

    if (!ss.fail() && ss.eof()) {
        return true;  // is-a-number
    } else {
        return false; // not-a-number
    }
}

Значение ss >> std::ws важно дляприем чисел с пробелами в конце, таких как "24 ".

Проверка ss.eof() важна для отклонения таких строк, как "24 abc".Это гарантирует, что мы достигли конца строки после прочтения числа (и пробела).

Испытательный жгут:

#include <iostream>
#include <iomanip>

int main()
{
    std::string tests[8] = {
            "", "XYZ", "a26", "3.3a", "42 a", "764", " 132.0", "930 "
    };
    std::string is_a[2] = { "not a number", "is a number" };
    for (size_t i = 0; i < sizeof(tests)/sizeof(std::string); ++i) {
        std::cout << std::setw(8) << "'" + tests[i] + "'" << ": ";
        std::cout << is_a [is_numeric (tests[i])] << std::endl;
    }
}

Вывод:

      '': not a number
   'XYZ': not a number
   'a26': not a number
  '3.3a': not a number
  '42 a': not a number
   '764': is a number
' 132.0': is a number
  '930 ': is a number
4 голосов
/ 07 февраля 2011

Вы должны использовать istringstream, чтобы он знал, что пытается проанализировать ввод.Кроме того, просто проверьте результат извлечения напрямую, а не используйте good позже.

#include <sstream>
#include <iostream>

int main()
{
    std::istringstream ss("2");
    double d = 0.0;
    if(ss >> d) {std::cout<<"number"<<std::endl;}
    else {std::cout<<"other"<<std::endl;}
}
0 голосов
/ 07 февраля 2011
int str2int (const string &str) {
  stringstream ss(str);
  int num;
  if((ss >> num).fail())
  { 
      //ERROR: not a number
  }
  return num;
}
...