简体   繁体   中英

C++ Validating Comma Placement in Numerical Input

I'm taking my first cs course and I'm currently learning the different ways to validate numerical inputs. Below is a bool function I wrote to check comma positions, but when I enter 65,000 it thinks the comma is in the wrong place.

bool commas(string input) {
    bool commas = true;
    long len = input.length();
    int counter = 0;

    for(int z = len-1; z >= 0; --z) {
        if(counter == 3) {
            if(input[z] != ',') {
                commas = false;
            counter = 0;
            }
        }
        else {
            if(input[z] == ',') {
                commas = false;
            }
            else {
                ++counter;
            }
        }
    }
    return commas;
}

The easiest way to figure out if the comma is in the correction position is to go backwards (starting from the rightmost character) within the string.

The reason why this is easier is that if you were to start from the leftmost character and go forward, when you encounter a , , you don't really know at that point whether that comma is in a valid position. You will only know until later on within the iteration process.

On the other hand, when you go from right-to-left, you know that if you encounter a comma, that comma is in a valid position -- there is no need to wait until you've gone further in the string to determine if the comma is valid.

To do this, it takes an adjustment in the loop to go backwards, and an additional counter to track the current group of 3 digits, since a comma can only occur after a group of 3 digits has been processed.

This is an untested example (except for the simple tests in main ):

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

bool commas(std::string input)
{
    // if the string is empty, return false
    if (input.empty())
        return false;

    // this keeps count of the digit grouping
    int counter = 0;

    // loop backwards
    for (int z = static_cast<int>(input.size()) - 1; z >= 0; --z)
    {
        // check if the current character is a comma, and if it is in
        // position where commas are supposed to be 
        if (counter == 3)
        {
            if (input[z] != ',')
                return false;

            // reset counter to 0 and process next three digits
            counter = 0;
        }
        else
        // this must be a digit, else error
        if (input[z] == ',')
            return false;
        else
            // go to next digit in group of 3
            ++counter;
    }

    // the first character must be a digit.
    return isdigit(static_cast<unsigned char>(input[0]));
}

int main()
{
    std::string tests[] = { "123,,345", 
                            "123,345",                                 
                            "123,345,678",
                            "12,345",
                            "1223,345",
                            ",123,345",
                            "1",
                            "",
                            "65,00",
                            "123"};

    const int nTests = sizeof(tests) / sizeof(tests[0]);
    for (int i = 0; i < nTests; ++i)
        std::cout << tests[i] << ": " << (commas(tests[i]) ? "good" : "no good") << "\n";
}

Output:

123,,345: no good
123,345: good
123,345,678: good
12,345: good
1223,345: no good
,123,345: no good
1: good
: no good
65,00: no good
123: good

The way this works is simple -- we just increment a counter and see if the current position we're looking at (position z ) in the string is a position where a comma must exist.

The count simply counts each group of 3 digits -- when that group of 3 digits has been processed, then the next character (when going backwards) must be a comma, otherwise the string is invalid. We also check if the current position is where a comma cannot be placed.

Note that at the end, we need to check for invalid input like this:

,123

This is simply done by inspecting the first character in the string, and ensuring it is a digit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM