Skip to main content
3 of 4
Code correction and simplification
Jerry Coffin
  • 34.1k
  • 4
  • 77
  • 145

I find this code rather difficult to follow. Right now, it seems to intermix code for determining whether a string constitutes a valid floating point value, with code for determining...other stuff you care about (something like allowing a number of floating point values together, maybe?)

I'd start with one that just determines whether a string is a valid floating point value. For the moment I'm assuming that means something like:

[-+]<digits>[.<digits>][[eE][-+]digits]

Almost all the parts of this are optional individually, but you do need at least one digit either in the "main" number (the part before the exponent). So 1e3 is valid, but just e3 is not (and likewise, either .1 or 1. is valid, but just . is not).

Code for that much might look something like this:

#include <cctype>
#include <string>
#include <iostream>

bool isValidDouble(std::string const &input) {
    unsigned pos = 0;
    unsigned digits = 0;

    while (std::isspace(input[pos])) {
        pos++;
    }

    if (input[pos] == '-' || input[pos]=='+') {
        pos++;
    }

    while (std::isdigit(input[pos])) {
        digits++;
        pos++;
    }

    if (input[pos] == '.') {
        pos++;
    }

    while (std::isdigit(input[pos])) {
        digits++;
        pos++;
    }

    if (digits == 0) {
        return false;
    }

    if (input[pos] == 'e' || input[pos] == 'E') {
        pos++;

        if (input[pos] == '-' || input[pos] == '+') {
            pos++;
        }

        if (!std::isdigit(input[pos])) {
            return false;
        }
        while (std::isdigit(input[pos])) {
            pos++;
        }
    }

    return pos == input.length();
}

int main() {
    std::string goodInputs[] = {
        "    1234",
        "   1.2",
        "\t0e2",
        "0.1e2",
        "1.",
        ".1",
    };

    std::string badInputs[] = {
        "e2",
        ".",
        "",
        "0.1e1-"
    };

    bool tests_passed = true;

    for (auto const &test : goodInputs) {
        if (!isValidDouble(test)) {
            tests_passed = false;
            std::cout << "Test failed for :" << test << "\n";
        }
    }

    for (auto const &test : badInputs) {
        if (isValidDouble(test)) {
            tests_passed = false;
            std::cout << "Test failed for : " << test << "\n";
        }
    }

    if (tests_passed) {
        std::cout << "All tests passed\n";
    }
}

I'm not entirely sure I understand what other validation you want, so I'll leave it at that for now.

Jerry Coffin
  • 34.1k
  • 4
  • 77
  • 145