Как вы ищете std :: string для подстроки в C ++? - PullRequest
7 голосов
/ 07 декабря 2008

Я пытаюсь разобрать простую строку в C ++. Я знаю, что строка содержит некоторый текст с двоеточием, за которым сразу следует пробел, а затем число. Я хотел бы извлечь только числовую часть строки. Я не могу просто разбить токены на пробел (используя sstream и <<), потому что текст перед двоеточием может содержать или не содержать пробелы. </p>

Некоторые примеры строк могут быть:

Общее дисковое пространство: 9852465

Свободное место на диске: 6243863

Секторов: 4095

Я бы хотел использовать стандартную библиотеку, но если у вас есть другое решение, вы также можете опубликовать его, так как другие с таким же вопросом могут захотеть увидеть другие решения.

Ответы [ 6 ]

14 голосов
/ 07 декабря 2008
std::string strInput = "Total disk space: 9852465";
std::string strNumber = "0";
size_t iIndex = strInput.rfind(": ");
if(iIndex != std::string::npos && strInput.length() >= 2)
{
  strNumber = strInput.substr(iIndex + 2, strInput.length() - iIndex - 2)
}
8 голосов
/ 07 декабря 2008

Для полноты вот простое решение в C:

int value;
if(sscanf(mystring.c_str(), "%*[^:]:%d", &value) == 1)
    // parsing succeeded
else
    // parsing failed

Объяснение: %*[^:] говорит о необходимости читать как можно больше символов, не являющихся двоеточиями, а * подавляет назначение. Затем читается целое число после двоеточия и любого пробела.

4 голосов
/ 07 декабря 2008

Я не могу просто токенизировать пространство (используя sstream и

Да, но вы можете использовать std::getline:

string not_number;
int number;
if (not (getline(cin, not_number, ':') and cin >> number)) {
    cerr << "No number found." << endl;
}
3 голосов
/ 07 декабря 2008

Я удивлен, что никто не упомянул регулярные выражения. Они были добавлены как часть TR1 и также включены в Boost . Вот решение с использованием регулярных выражений

typedef std::tr1::match_results<std::string::const_iterator> Results;

std::tr1::regex re(":[[:space:]]+([[:digit:]]+)", std::tr1::regex::extended);
std::string     str("Sectors: 4095");
Results         res;

if (std::tr1::regex_search(str, res, re)) {
    std::cout << "Number found: " << res[1] << std::endl;
} else {
    std::cerr << "No number found." << std::endl;
}

Похоже, гораздо больше работы, но вы получаете больше от этого ИМХО.

3 голосов
/ 07 декабря 2008

Аналогично ответу Конрадса, но с использованием istream::ignore:

int number;
std::streamsize max = std::numeric_limits<std::streamsize>::max();
if (!(std::cin.ignore(max, ':') >> number)) {
    std::cerr << "No number found." << std::endl;
} else {
    std::cout << "Number found: " << number << std::endl;
}
2 голосов
/ 07 декабря 2008
const std::string pattern(": ");
std::string s("Sectors: 4095");
size_t num_start = s.find(pattern) + pattern.size();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...