    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: ISBN Numbers</title>
        <link>https://members.accu.org/index.php/articles/913</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + CVu Journal Vol 11, #5 - Aug 1999</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c130/">115</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-130/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+130/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;ISBN Numbers</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 August 1999 13:15:32 +01:00 or Tue, 03 August 1999 13:15:32 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p>The problem:- validate a number input by a user as an ISBN
number The solution<sup>[<a name="d0e24" href="#ftn.d0e24" id=
"d0e24">1</a>]</sup> :- A C script</p>
<p>This (flawed) program came about when I found out how ISBN
numbers were created.</p>
<p>Some samples:-</p>
<p>0-672-31022-8 1-55828-552-0 0-88022-519-X</p>
<p>The format for the numbers is not as important as the
calculation. After taking out the hyphens there are ten digits, and
each one represents its own value, i.e., 0 = 0, 1 = 1, 2 = 2, etc.
X is the symbol for the value ten<sup>[<a name="d0e36" href=
"#ftn.d0e36" id="d0e36">2</a>]</sup>.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e40" id="d0e40"></a>The Rules</h2>
</div>
<p>Starting from the left, each number is multiplied by a value,
starting with 10 and decrementing by 1 for each successive digit,
so the second number is multiplied by nine, the third by eight etc,
and the tenth by 1. All 10 numbers are then added together and the
result must be divisible by eleven, or it is not a true ISBN
number.</p>
<p>The first thing I had to do was accept a number from the user in
the ISBN format, and strip out all the hyphens. As there is a
mixture of characters, and more importantly, some would be kept
while others rejected, and the input was from the keyboard, I
decided to capture the input into a function, <tt class=
"function">validate(int)</tt>. The number is tested and the user is
given the result. The first exercise was to restrict what the user
could enter to only three items, digits 0 - 9, hyphens and the
letter X, in either lower or upper case.</p>
<p>Some constant declarations</p>
<pre class="programlisting">
#define ISBN 14
#define MAX 10
enum { FALSE, TRUE };
</pre>
<p>Here is the validate function:-</p>
<pre class="programlisting">
void validate(int length){
  int loop, reply = 1;
  char input[ISBN];
  char output[ISBN];
  char keystroke = '\0';
  int valid;
  /* enter characters until the return is hit
   * which will terminate the input to be checked  */
  for(loop = 0; (loop &lt; length) &amp;&amp; keystroke != 13; loop++) {
    do {
      valid = TRUE;
      keystroke = getch();
      input[loop] = keystroke;
  /* check that only numbers 0 to 9,
  * RETURN,  character's '-' 'x' or  'X' are entered  */
      if(keystroke &lt; 48 &amp;&amp; keystroke != '-' &amp;&amp;
         keystroke != 13 || keystroke &gt; 57 &amp;&amp;
         keystroke != 'x' &amp;&amp; keystroke != 'X')
        valid = FALSE;
  /* if the character is unacceptable
   * let the user know and allow them to  continue inputting  */
      if(valid == FALSE) printf(&quot;\a&quot;);
    } while(valid == FALSE);
    printf(&quot;%c&quot;, input[loop]);
  }
  input[loop] = '\0';
</pre>
<p>Before the function ends there are three more jobs to do,
firstly call a function for the user to check that they have input
the number correctly now that it has been validated as a true ISBN
category number<sup>[<a name="d0e60" href="#ftn.d0e60" id=
"d0e60">3</a>]</sup></p>
<pre class="programlisting">
  check(input);
</pre>
<p>then make a copy of the input, this dummy has been created
because the input is altered by the check function so the output
would be numbers without the dashes</p>
<pre class="programlisting">
  strcpy(output, input);
</pre>
<p>and finally call a function to remove the dashes from the string
so that it can be treated as a number</p>
<pre class="programlisting">
  reply = dashes(output);
</pre>
<p>Now that the user is happy with the number that they have
entered after it has been checked to see that it fits in with the
rules, the dashes have to be removed so that the string can be
converted to a number so that it can be checked to see if it is
divisible by eleven</p>
<pre class="programlisting">
int dashes(char *start){
  int number, result = 0;
  int loop, index = 0;
  clrscr();
  for(loop = 0; loop &lt; ISBN; loop++) {
    if(start[index] == '-')
      strcpy(&amp;start[index], &amp;start[index + 1]);
    index++;
  }
</pre>
<p>call a function to multiply each element by an incrementing
number, totalling all the elements and returning the total so that
it can be tested for division by eleven.</p>
<pre class="programlisting">
  number = isbntest(start);
  result = (number % ISBN);
  if(result != 0) {
    puts(&quot;This is not a valid ISBN number&quot;);
    puts(&quot;press any key to continue. . . &quot;);
    getch();
  }
</pre>
<p>the reason why the OK message is not here is that there are no
longer any dashes in the string so presentation on the screen would
not look so good.</p>
<p>All that is left to do is test the number against the rules,
this function does a lot of work despite its simplicity it takes
each element of the array and multiplies it by count which then
decrements through the loop</p>
<pre class="programlisting">
int isbntest(char *start) {
  int loop, sum = 0, result = 0;
  int count = MAX, end[MAX] = { 1,1,1,1,1,1,1,1,1,1 };
  clrscr();
  for(loop = 0; loop &lt; MAX; loop++) {
    if(start[loop] == '0') end[loop] = (0 * count);
    if(start[loop] == '1') end[loop] = (1 * count);
  if(start[loop] == '2') end[loop] = (2 * count);
  if(start[loop] == '3') end[loop] = (3 * count);
  if(start[loop] == '4') end[loop] = (4 * count);
  if(start[loop] == '5') end[loop] = (5 * count);
  if(start[loop] == '6') end[loop] = (6 * count);
  if(start[loop] == '7') end[loop] = (7 * count);
  if(start[loop] == '8') end[loop] = (8 * count);
  if(start[loop] == '9') end[loop] = (9 * count);
  if(start[loop] == 'x' || start[loop] == 'X')
    end[loop] = (10 * count);
  count--;
  }
  for(loop = 0; loop &lt; MAX; loop++) 
                      sum += end[loop];
  result = (sum % 11);
  return result;
}
</pre>
<p>All the contents of the loop are added together and the final
sum is tested to see if it is a multiple of eleven to prove that it
is a true ISBN number.</p>
<p>The full program is available if required, and I hope this has
been useful for anyone in their current work, or if it brings any
other items to mind, or if you know a better way to check for
ISBN's. Okay, truth time, I wrote this in February 1998, it is the
last C program that I produced at the end of my first year learning
to program, and I had just started to learn C++ [which I am still
trying to do] ;-) I can see some mistakes with the above, i.e.,</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>the enum is unnecessary as there is a standard bool type
now,</p>
</li>
<li>
<p>the mixture of numbers, letters and symbols here is extremely
poor</p>
<pre class="programlisting">
      if(keystroke &lt; 48 &amp;&amp; keystroke != '-' &amp;&amp;
         keystroke != 13 || keystroke &gt; 57 &amp;&amp;
         keystroke != 'x' &amp;&amp; keystroke != 'X')
       valid = FALSE;
</pre></li>
<li>
<p>the function <tt class="function">dashes(char*)</tt> should be
called <tt class="function">removeDashes(char*)</tt>,</p>
</li>
<li>
<p>perhaps a <tt class="literal">switch</tt> would be better than
all those <tt class="literal">if</tt>'s in <tt class=
"function">isbnTest(char*)</tt></p>
</li>
</ol>
</div>
<p>however, its the mistakes that I cannot see that I need help
with, and why I read C Vu and Overload.</p>
<p class="c2"><span class="remark">Thanks, Paul. There are several
defects in your code. I have highlighted one in the footnotes I
have added, but there are others. Not least is that some people use
spaces to format their ISBN numbers, not strictly correct but I
think it would be picky to reject a potential ISBN simply because
of that. Another problem is that your solution requires raw
keyboard processing which is not always easily
available.</span></p>
<p class="c2"><span class="remark">I suggest that the problem
should split into two parts: capturing a data-string which is a
potential ISBN and then validating it. In the first part, keyboard
input is only one of several potential methods (e.g. get data from
a database). In the second part I think that a clear distinction
should be made between the body of the ISBN and the final
check-digit. Perhaps allowance should also be made for SBNs (they
have eight not nine digits in the body and can be converted to
ISBNs by prefixing them with a 0). I think much could be done to
produce a cleaner solution, but let the readers have a go
first.</span></p>
<p class="c2"><span class="remark">And what about ISSNs? Actually I
do not know if there are any validation rules for these.</span></p>
</div>
<div class="footnotes"><br>
<hr class="c3" width="100">
<div class="footnote">
<p><sup>[<a name="ftn.d0e24" href="#d0e24" id=
"ftn.d0e24">1</a>]</sup> Writing a program to do this was one of my
standard pupil exercises in the days when I was a teacher. Of
course my students wrote the code in Forth &#9786; I feel that this
sort of task is well suited to scripting languages. I would be
happy to publish alternative solutions in the language of your
choice: C, C++. Java, Python, awk etc. I would also encourage the
multi-lingual readers to do a comparison between ease of solution
in several languages.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e36" href="#d0e36" id=
"ftn.d0e36">2</a>]</sup> X can only occur as the final
(check-)digit</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e60" href="#d0e60" id=
"ftn.d0e60">3</a>]</sup> Astute readers will realise that there is
a slight flaw in this algorithm. How should we eliminate 'X' as
anything other than a final check-digit.</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
