Skip to main content
Use standard algorithm
Source Link
Toby Speight
  • 88.3k
  • 14
  • 104
  • 327

You do need to include <string>. Your platform seems to bring it in as a side-effect of other includes, but you can't portably rely on that.

If there's no need to modify the contents of the string, prefer to pass by reference, to reduce copying:

bool string_contains_integer(const std::string& str)
//                           ^^^^^            ^

Instead of looping with indexes, learn to use iterators. If you really must use indexes, use the correct type (std::string::size_type, not unsigned long long).

We don't need to write our own loop by hand, as there's a standard algorithm that will do that for us; we just need to supply the correct predicate function:

#include <algorithm>
#include <iostream>
#include <string>

bool string_contains_integer(const std::string& str)
/*
    This function iterates through an array of chars,
    and checks each character to be a digit;
    optionally including a starting "+/-" sign.

    Returns true if the string contains a number (string of digits);
    Returns false if the string contains any other character(s).

    Starting "+/-" gets ignored, as we accept all integer numbers.
*/
{
    auto from = str.begin();
    auto to = str.end();

    if (from == to) {
        return false;
    }

    if (*from == '+' || *from == '-') {
        ++from;
    }

    return from != to
        && std::all_of(from, to,
                       [](unsigned char c){ return std::isdigit(c); });
}

You do need to include <string>. Your platform seems to bring it in as a side-effect of other includes, but you can't portably rely on that.

If there's no need to modify the contents of the string, prefer to pass by reference, to reduce copying:

bool string_contains_integer(const std::string& str)
//                           ^^^^^            ^

Instead of looping with indexes, learn to use iterators. If you really must use indexes, use the correct type (std::string::size_type, not unsigned long long).

You do need to include <string>. Your platform seems to bring it in as a side-effect of other includes, but you can't portably rely on that.

If there's no need to modify the contents of the string, prefer to pass by reference, to reduce copying:

bool string_contains_integer(const std::string& str)
//                           ^^^^^            ^

Instead of looping with indexes, learn to use iterators. If you really must use indexes, use the correct type (std::string::size_type, not unsigned long long).

We don't need to write our own loop by hand, as there's a standard algorithm that will do that for us; we just need to supply the correct predicate function:

#include <algorithm>
#include <iostream>
#include <string>

bool string_contains_integer(const std::string& str)
/*
    This function iterates through an array of chars,
    and checks each character to be a digit;
    optionally including a starting "+/-" sign.

    Returns true if the string contains a number (string of digits);
    Returns false if the string contains any other character(s).

    Starting "+/-" gets ignored, as we accept all integer numbers.
*/
{
    auto from = str.begin();
    auto to = str.end();

    if (from == to) {
        return false;
    }

    if (*from == '+' || *from == '-') {
        ++from;
    }

    return from != to
        && std::all_of(from, to,
                       [](unsigned char c){ return std::isdigit(c); });
}
Source Link
Toby Speight
  • 88.3k
  • 14
  • 104
  • 327

You do need to include <string>. Your platform seems to bring it in as a side-effect of other includes, but you can't portably rely on that.

If there's no need to modify the contents of the string, prefer to pass by reference, to reduce copying:

bool string_contains_integer(const std::string& str)
//                           ^^^^^            ^

Instead of looping with indexes, learn to use iterators. If you really must use indexes, use the correct type (std::string::size_type, not unsigned long long).