Skip to main content
corrected UB in use of cctype functions
Source Link
Jerry Coffin
  • 34.1k
  • 4
  • 77
  • 145
#include <cctype>
#include <string>
#include <iostream>

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

    while (std::isspace(static_cast<unsigned char>(input[pos]))) {
        pos++;
    }

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

    while (std::isdigit(static_cast<unsigned char>(input[pos]))) {
        digits++;
        pos++;
    }

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

    while (std::isdigit(static_cast<unsigned char>(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(static_cast<unsigned char>(input[pos]))) {
            return false;
        }
        while (std::isdigit(static_cast<unsigned char>(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";
    }
}
#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";
    }
}
#include <cctype>
#include <string>
#include <iostream>

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

    while (std::isspace(static_cast<unsigned char>(input[pos]))) {
        pos++;
    }

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

    while (std::isdigit(static_cast<unsigned char>(input[pos]))) {
        digits++;
        pos++;
    }

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

    while (std::isdigit(static_cast<unsigned char>(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(static_cast<unsigned char>(input[pos]))) {
            return false;
        }
        while (std::isdigit(static_cast<unsigned char>(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";
    }
}
Code correction and simplification
Source Link
Jerry Coffin
  • 34.1k
  • 4
  • 77
  • 145
#include <ctype><cctype>
#include <string>
#include <iostream>

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

    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') {
        if (digitspos++;

 == 0) {
     if (input[pos] == '-' || input[pos] == return'+') false;{
        }
    pos++;
    exponent = true;
  }

      pos++;
  if (!std::isdigit(input[pos])) }
{
    if (exponent && input[pos] == '-' || input[pos] == '+')return {false;
        pos++;}
    }

    while (exponent && 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";
    }
}
#include <ctype>
#include <string>
#include <iostream>

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

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

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

    while (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') {
        if (digits == 0) {
            return false;
        }
        exponent = true;
        pos++;
    }

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

    while (exponent && 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",
        ".",
        ""
    };

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

    for (auto const &test : badInputs) {
        if (isValidDouble(test)) {
            std::cout << "Test failed for : " << test << "\n";
        }
    }
}
#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";
    }
}
added 1529 characters in body
Source Link
Jerry Coffin
  • 34.1k
  • 4
  • 77
  • 145

Code for that much might look something like this:

#include <ctype>
#include <string>
#include <iostream>

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

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

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

    while (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') {
        if (digits == 0) {
            return false;
        }
        exponent = true;
        pos++;
    }

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

    while (exponent && 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",
        ".",
        ""
    };

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

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

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

Code for that much might look something like this:

#include <ctype>
#include <string>
#include <iostream>

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

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

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

    while (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') {
        if (digits == 0) {
            return false;
        }
        exponent = true;
        pos++;
    }

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

    while (exponent && 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",
        ".",
        ""
    };

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

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

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

Source Link
Jerry Coffin
  • 34.1k
  • 4
  • 77
  • 145
Loading