Book class: checking ISBN with a constructor

Hello,
I'm working on Chapter 9, exercise 5 of "Programming: Principles and Practice Using C++" by Bjarne Stroustrup. In the exercise, I'm supposed to create a book class, with ISBN, author, title, copyright, etc. My concern lies with the ISBN check in my constructor(I haven't added the others yet)--I'm wondering if there's a better way to check it as it is. I decided to use a string to represent the ISBN because it's easier to manipulate input/output (for an end-user), rather than using a struct(easier checking)... or something I may not know or have have thought of.

Here's my code for the constructor (it works fine):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Book::Book(string ISBN) :isbn(ISBN) //will add other types later
{ //ISBN must be integer-integer-integer-digit/letter

	stringstream ss(isbn); //book didn't cover stringstreams yet???
	char valid='-';
	char invalid=' '; //ANYTHING other than '-' is invalid...

	//check the first three sections for an integer followed by a '-'
	for(int index=0; index<3; index++) {
		int integer=-1;
		char character=invalid; //both initialized for precaution
		ss >> integer >> character;
		if(integer<0 || character!=valid) rpt_err("Invalid ISBN.\n");
	}
	string final;
	ss >> final; //check the remaining character(s)???

	if(final.size()!=1) rpt_err("Invalid ISBN.\n"); //only a single number/letter allowed
	else if(!isdigit(final[0]) && !isalpha(final[0])) rpt_err("Invalid ISBN.\n"); //separate check to prevent range errors
}


Any suggestions?
' ' is a space character, not "any character".

The problem with this is, it requires a '-' at the END of the isbn. The easiest variant (albeit maybe a bit of an overkill) would be to use regular expressions.
Yes, I'm aware that ' ' isn't just any character, but thanks... that comment was meant to show that I chose an arbitrary character to represent invalid--that literally anything else (other than '-')could have been placed there. I needed to chose something to re-initialize "character" with....

I'm not sure what you mean by "regular expressions." I'm learning on my own here... could you perhaps elaborate/demonstrate? From what I can tell, you're suggesting that I use three different integers and a character to represent the ISBN--not worrying about the dashes.

I updated my code... I noticed that it wasn't throwing for whitespace characters (see line 8). Here is the whole updated copy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Book::Book(string ISBN) :isbn(ISBN) //will add other types later
{ 
//ISBN must be integer-integer-integer-digit/letter
	stringstream ss(isbn);
	char valid='-';
	char invalid=' '; //ANYTHING other than '-' is invalid...
	int printable=33;
	for(int index=0; index<isbn.size(); index++) if(isbn[index]<printable) rpt_err("Invalid ISBN.\n"); //throws with whitespace

	//check the first three sections for an integer followed by a '-'
	for(int index=0; index<3; index++) {
		int integer=-1;
		char character=invalid; //both initialized for precaution
		ss >> integer >> character;
		if(integer<0 || character!=valid) rpt_err("Invalid ISBN.\n");
	}
	string final;
	ss >> final; //check the remaining character(s)

	if(final.size()!=1) rpt_err("Invalid ISBN.\n"); //only a single number/letter allowed
	else if(!isdigit(final[0]) && !isalpha(final[0])) rpt_err("Invalid ISBN.\n"); //separate check to prevent range errors
}
Ah, I see what you did there now.

About regular expressions: http://en.wikipedia.org/wiki/Regular_expression
- pretty useful when dealing with strings that have to have a specific format.

Another option would be doing it like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool acceptHyphen = false;
bool correctlyFormed = true;
for(int i=0; i<isbn.length(); ++i)
{
   if(isbn[i]>='0' && isbn[i]<='9')
   {
         acceptHyphen = true;
   } else if(acceptHyphen && isbn[i]=='-' && !(i==(isbn.length()-1))) {
         acceptHyphen=false;
   } else {
         correctlyFormed = false;
         break;
   }
}


Note that that only checks if the string consists of numbers that are seperated by hyphens, not if it is an actually valid ISBN.
Last edited on
Topic archived. No new replies allowed.