Validate a string is only digits and only a certain length

4113 views c++
0

So I have an issue.

I need to take a string (I cannot have it as an int, it has to be defined as a string) and inside of the set method, I have to validate that the number is either 9 or 13 digits long and contains only digits.

I can validate the length using str.length() but I cannot get it to validate that the input only contains digits.

Here is my current code:

void Book::setISBN(string ISBN) 
{

//validate the length here  ALSO NEED TO VALIDATE ITS A NUMBER

if (ISBN.length() >= 9 && ISBN.length() <= 13) {

    this->ISBN = ISBN;
}
else {
    this->ISBN = '0';
}
}

This is the code which it will pull the information:

Book b = Book();
b.setISBN("23");
b.setAuthor("R.L. Stine");
b.setTitle("Goosebumps");
b.setPrice(25.00);

Book b2 = Book("thisisshith", "Stephen King", "IT", 20.32);

The first part, b works as the setISBN("23") will return with a zero but the b2 "thisisshith" returns just like that. I need it to return as 0 as well. If it was a set of digits between 9-13 in length then it would return correctly.

Any help would be appreciated.

I have tried isdigit() but says it cannot convert between a string and int.

answered question

"either 9 or 13 digits long" and "digits between 9-13 in length" are contradictory requirements. Which one do you actually need? EXACTLY 9 or 13 digits, or BETWEEN 9 and 13 digits?

I literally quoted the assignment there. So I am going to assume either 9 digits or 13 digits. However, as I stated, the length is not what I am needing, I am needing to be able to validate they are ONLY numerical, non-alphabetical.

2 Answers

3

Try this:

void Book::setISBN(string ISBN) 
{
    if (((ISBN.length() == 9) || (ISBN.length() == 13)) &&
        (ISBN.find_first_not_of("0123456789") == string::npos))
    {
        this->ISBN = ISBN;
    }
    else
    {
        this->ISBN = '0';
    }
}

If you want to use isdigit() instead, you need a loop to check each char in the string individually:

#include <ctype.h>

void Book::setISBN(string ISBN) 
{
    if ((ISBN.length() == 9) || (ISBN.length() == 13))
    {
        for (int i = 0; i < ISBN.length(); ++i)
        {
            if (!::isdigit(ISBN[i]))
            {
                this->ISBN = '0';
                return;
            }
        }
        this->ISBN = ISBN;
    }
    else
    {
        this->ISBN = '0';
    }
}

Or, you can use isdigit() in a predicate for standard algorithms like std::find() or std::all_of():

#include <algorithm>
#include <ctype.h>

void Book::setISBN(string ISBN) 
{
    if ((ISBN.length() == 9) || (ISBN.length() == 13))
    {
        if (std::find(ISBN.begin(), ISBN.end(), [](int ch){ return !::isdigit(ch); }) == ISBN.end())
        {
            this->ISBN = ISBN;
            return;
        }
    }
    this->ISBN = '0';
}

#include <algorithm>
#include <ctype.h>

void Book::setISBN(string ISBN) 
{
    if ((ISBN.length() == 9) || (ISBN.length() == 13))
    {
        if (std::all_of(ISBN.begin(), ISBN.end(), [](int ch){ return (::isdigit(ch) != 0); }))
        {
            this->ISBN = ISBN;
            return;
        }
    }
    this->ISBN = '0';
}

posted this
11

Figured it out!

There is also a part in the code that is:

Book::Book(string ISBN, string author, string title, double price) {
this->ISBN = ISBN;
this->author = author;
this->title = title;
this->price = price;`

I added this to the end of that line:

    if ((ISBN.length() == 9) || (ISBN.length() == 13) &&
    ISBN.find_first_not_of("0123456789") == string::npos)
{
    this->ISBN = ISBN;
}
else {
    this->ISBN = '0';
}

This fixes what I need fixed. Thanks!

posted this

Have an answer?

JD

Please login first before posting an answer.