Member Avatar for Brian Perrigan

I've been given a homework assignment that goes as follows:

We will write a program which inputs a 10-place ISBN number, cleans
it up (removes spaces, and punctuation,) then strips the last digit
(saving it) then re-calculates that last (check) digit from the rest of
the number. If the result of our calculation matches the saved check
digit, the function will validate the ISBN number, otherwise the function
will sound an alarm. See the bottom of this file for some sample runs.

NOTE: THE LAST (CHECK) DIGIT CAN BE EITHER A DIGIT OR AN 'X'. That
requires care on your part. Don't toss out a valid 'x' just because
it's not a digit.

I want to take it one step at a time so I am trying to test if I can intake a string and clean it up first.

I wrote up this code:

#include <iostream>
#include <string>
#include <sstream>
using namespace std ;

int main ()
{
	char promptisbn [] = "Plese Enter 10 Digit ISBN" ;
	string isbn ;
	int x = 0 ;

	cout << promptisbn << endl ;
	getline (cin, isbn) ;

		for ( x ; x < isbn.length() ; x++ )
			if ( !isdigit(isbn[x] && toupper(isbn[x])!= 'X') )
				isbn.erase (x,1) ;
	cout << isbn ;
	getchar () ;
}

And if I input this number:
ISBN 0-321-40939-6

I get a return value of:
SN0314996

It's cleaning up every other number... I'm not sure why :/ I think it has something to do with the:

isbn.erase (x,1)

I've tried changing it to (x,0) & (x) and (x,2) to see what it does. But I cannot figure out how to make it just go through and erase the characters I don't want.

I appreciate your time and any insight you may have. Thank you so much.

`B

The erase function is removing the char at the Nth location, which puts the N+1-th char in the Nth location, then the code increments the index to look at the nextchar, skipping the one that just got moved. If I were doing it along the lines you are starting with, I'd build the clean ISBN in a new std::string rather than trying to do it in place: Just makes it a lot easier to think about. Something like std::string cleanIsbn = ""; ...; cleanIsbn.append(isbn[x]); Since this is C++, you can (and should) use the keyword const when appropriate. I'd make line 8 look like: const char *isbnprompt = "..." ... or better yet, make it a const std::string

commented: Good ideas +4
Member Avatar for Brian Perrigan

So you mean that while the for loop is executing it should be sending the data it's correcting to a new string...

string cleanisbn ;

for example? I like this idea it's logical since it's input --- process --- output

how would I do that?
I don't expect you to write it for me, I appreciate the help already, but for example your line:

std::string cleanIsbn = ""; ...; cleanIsbn.append(isbn[x]);

corresponds to what line of code in the for loop?
could you clarify the command

std::string cleanIsbn = ""; ...; cleanIsbn.append(isbn[x]);

defines cleanIsbn as a string equal to (here's where i'm confused) then adds the the cleanIsbn string the contents of (isbn[x]) ???

Thanks.

Member Avatar for Brian Perrigan

So it's almost like you're saying

Have A & B strings be equal.
Check A and delete in B... continue to check A but keep deleting in B... at the end export B?

No I mean make string cleanIsbn be the empty string. Walk through the characters in isbn one at a time. If the current char is a valid ISBN char, append it to cleanIsbn , else don't. When you have seen all the characters in isbn , cleanIsbn is a clean copy.

Be very thoughtful about that 'X': It is only valid if it is the last (non space) character. (I wonder what you should do if the clean copy isn't 10 char long?)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.