Count decimal numbers in a string using the standard library

Viewed 173

I have white-space separeted integers inside a string, e.g.:

std::string s = "1 2 33 444 0 5";

The string is well-formed: just white-space separated numbers without any letters, new-lines, etc.


How to count the number of integers in the above string in an STL way? I am looking for something "short" that will use e.g. iterators or <algorithm>.

5 Answers

std::count_if(s.begin(),s.end(), [](unsigned char c){ return std::isspace(c);}) + 1


Edit:

If there are multiple/varying spaces between chars, then you can change the lambda to:

    [](unsigned int c)
    { 
        static bool prev = false;
        bool current = isspace(c);
        bool new_space = !prev && current;
        prev = current;
        
        return new_space;
    }

A simple way is to use string streams:

#include <iostream>
#include <sstream>

int main()
{
    int temp;
    int count = 0;
    std::string s = "1 2 33 444 0 5";

    std::stringstream ss(s);
    while(ss >> temp){
        count++;
    }
    std::cout << count; //test print
    return EXIT_SUCCESS;
}

Note that this will only count parseabe values, for instance, if a non-numeric character is found (appart from spaces) it will stop counting. It also works for multiple spaces.

This solution uses only the STL, has no loops, and will handle arbitrary number of leading, trailing, and extra whitespace:

std::string s = "1 2 33 444 0 5";
std::stringstream ss(s);

int const count = std::distance(std::istream_iterator<int>{ss},
                                std::istream_iterator<int>{}); 

Here's a demo.

Are the integers guaranteed to each be separated by a single whitespace character (without there being leading or trailing whitespace)?

If so, then you just need to add 1 to the number of whitespace chars in the string itself, accounting for the empty string being a special case.

#include <algorithm>

size_t intCount(const std::string& s) {
  if (s.size() == 0) {
    return 0;
  }

  return std::count(s.begin(), s.end(), ‘ ‘) + 1;
}

You can use regular expressions:

#include <iterator>
#include <regex>
#include <string>

std::string s = "1 2 33 444 0 5";

const std::regex regex("\\d+");
const auto n = std::distance(
    std::sregex_iterator(s.begin(), s.end(), regex),
    std::sregex_iterator());

This will handle multiple, leading and trailing whitespaces automatically. This approach doesn't impose any limitation on the length of each integer.

Related