home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / CNEWS018.ZIP / CNEWS018.DOC < prev    next >
Text File  |  1989-12-29  |  74KB  |  2,042 lines

  1.  
  2.  
  3.       Issue                        C News                             2
  4.  
  5.  
  6.       ================================================================= 
  7.       THE HEAP by Barry Lynch    
  8.       ================================================================= 
  9.  
  10.  
  11.  
  12.            The postcards keep coming and we truly appreciate the
  13.       support that has been shown over the last two years.  This issue
  14.       of C News marks the end of Volume 1 of C News.  And beginning
  15.       with Issue 19, we will start Volume 2 with a few new twists.
  16.       (Can't say what they are yet, still working out the details...) 
  17.  
  18.            This issue contains another installment of Wayne
  19.       Dernoncourt's Beginner's Column.  This month Wayne starts
  20.       exploring the wondrous world(???) of sort algorithms.  Wayne's
  21.       article started as a result of a C News staff meeting we had at
  22.       a local pizzeria a few months ago.  Matter of fact, quite a few
  23.       things had their start that night at the pizzeria.  
  24.  
  25.            Roy Browning took the time to sit down and write a few
  26.       words on his explorations into C++.  While I can't claim Roy as
  27.       the official C News "C++" guru, we can look forward to his
  28.       thoughts as he discovers more about C++.  Welcome aboard Roy! 
  29.  
  30.            Paul Castle sent us an article on command line parsing
  31.       which does a nice job of explaining the concepts of command line
  32.       parsing to beginner C programmers.  
  33.  
  34.            Jim Singleton - who is beginning to take over C News (grin)
  35.       - starts a series on software development in this issue.  If you
  36.       recall, from a previous issue of C News, Jim and I started
  37.       developing an Opus utility to measure my BBS system usage.
  38.       Alas, Dan Kozak decided to show off and wrote an AWK script to
  39.       accomplish the same thing.  Before Jim and I could get started,
  40.       Dan was already over the finish line.  Well after that
  41.       embarrassing episode, Jim threatened Dan with bodily harm if he
  42.       showed off again.  So I think we can safely assume that Jim's
  43.       article will continue in the next issue.  
  44.  
  45.            Announcing the Official C News t-shirt and coffee mug.  All
  46.       contributors to C News get an official C News "Author" t-shirt,
  47.       and a coffee mug.  Anyone else that wants one will have to
  48.       purchase them at cost.  Remember that night at the pizzeria?
  49.       Well this is one of the ideas that came out of the discussion.
  50.       It seems that while Jim Singleton was riding on the steam train
  51.       ride at SOGEAST 89, he started talking to Dave Thompson
  52.       (Micro-Cornucopia Editor) about C News.  It turns out that in
  53.       the early days of MicroC, they used to give T-shirts to
  54.       contributors instead of money.  So after Jim came back from the
  55.       SOG, he dropped the idea of a C News T-shirt.  Well, I thought
  56.       it wasn't a bad idea and now they are available in blue only.
  57.       Next year we will pick another colour.  
  58.  
  59.  
  60.       
  61.  
  62.  
  63.       Issue                        C News                             3
  64.  
  65.  
  66.  
  67.            Remember the old saying "if you need something done give it
  68.       to the busiest person?"  Well if you don't, I do and that is the
  69.       story of my life these days.  Some of you may have noticed that
  70.       I do not have as big a part in C News as I used to.  It isn't
  71.       that I do not want to, but simply that work commitments are
  72.       taking all of my free time.  However, Jim, Dan and Wayne have
  73.       done a great job of getting this issue of C News together.  With
  74.       their continued support I have no doubt that 1990 will be a
  75.       bigger and better year for C News.  
  76.  
  77.       Barry 
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.       
  121.  
  122.  
  123.       Issue                        C News                             4
  124.  
  125.  
  126.       ================================================================= 
  127.       MAGAZINE REVIEW - INSIDE TURBO C by Jim Singleton
  128.       ================================================================= 
  129.  
  130.  
  131.       (NOTE: I initially reviewed "Inside Turbo C" after the first
  132.       issue, prior to publishing the review, I received issue number
  133.       two.  Therefore, reviews of both issues appear here.) 
  134.  
  135.       Issue:  Volume 1, Number 1   September 1989
  136.       Publisher:  The Cobb group
  137.                   P.O. Box 24412
  138.                   Louisville, KY  40224-9960
  139.  
  140.            "Inside Turbo C" is a new newsletter/magazine, published by
  141.       The Cobb Group, Inc.  As the title suggests, the subject matter
  142.       is Turbo C.  At sixteen pages in length, "Inside Turbo C" does
  143.       not take too long to read, especially since approximately half
  144.       of each issue is source code (seven pages in this issue).  While
  145.       the articles are clear and concise, they do not attempt to go
  146.       into any topic in depth.  It will be interesting to see if in
  147.       future issues there are articles which span several issues.  The
  148.       first issue contains articles on interrupts, binary trees, and
  149.       fast screen input/output.  
  150.  
  151.            As mentioned, each issue contains source code.  My biggest
  152.       complaint, as far as the appearance of the source code, is that
  153.       it is printed with line numbers, which actually makes it look
  154.       somewhat confusing.  In addition, because of the length of each
  155.       issue, none of the articles really explore any topic in any
  156.       great depth.  The biggest problem is that there are errors in
  157.       the source code.  I know this often happens in books and
  158.       magazines, but here we are talking about a newsletter and I
  159.       don't think it should be too hard to check the source code prior
  160.       to publication.  In fact, one listing is incomplete, it's
  161.       missing a number of lines of code.  
  162.  
  163.            In addition to the newsletter, subscribers also have access
  164.       to Cobb Group Information Services (CGIS) an on-line information
  165.       exchange from The Cobb Group.  The Basic Service, which is free
  166.       to all subscribers, allows the user 15 minutes per day, a back
  167.       issues directory, product news, and an information center.  A
  168.       Premium Service is also available, which allows users to
  169.       download source code, no time limit, on-line conferencing, and
  170.       the features included with the Basic Service.  The Premium
  171.       Service is currently available at an "introductory rate" of $30 
  172.       a year.  
  173.  
  174.            Speaking of costs, how much is "Inside Turbo C"?  A year's
  175.       subscription costs $59.  Actually, considering that the cover
  176.       price is $7, this represents a savings of $25.  The price is the
  177.       biggest strike against "Inside Turbo C".  It's too expensive for
  178.  
  179.  
  180.       
  181.  
  182.  
  183.       Issue                        C News                             5
  184.  
  185.  
  186.       its size, especially since there are a number of other
  187.       newsletters and magazines devoted to C.  (As a matter of fact,
  188.       you're reading one now.) 
  189.  
  190.       ------------------------------------------------------------ 
  191.  
  192.       Issue:  Volume 1, Number 2   October 1989 
  193.  
  194.            I wasn't too impressed with the first issue, of "Inside
  195.       Turbo C", so how was issue 2?  Don't ask.  Once again, the
  196.       articles are clearly written.  So much for the good news.  
  197.  
  198.            Actually, the article on spawning a child process isn't too
  199.       bad, nor is the article on conditional compiling.  The article
  200.       on choosing memory models seems out of place.  If the audience
  201.       for "Inside Turbo C" is beginners, which is how the article on
  202.       spawning a child process is written (along with the introduction
  203.       to pointers article and the article on sound generation), this
  204.       article is almost useless.  All this article really is, is a
  205.       definition of each memory model and it takes less than a page to
  206.       explain all of them.  (A much better article on memory models
  207.       appears in issue 11 of the "C News".)  If the information in the
  208.       Turbo C manuals isn't clear, this isn't going to help much
  209.       more.  
  210.  
  211.            Well, is the source code any better?  The source code for
  212.       the article on pointers is long and hard to follow.  An article
  213.       which is intended as an introduction to pointers should have
  214.       clear and concise examples as source code.  Also, the one
  215.       include file, mcalc.h, makes me think the code is from the
  216.       examples provided by Borland when you purchase Turbo C.  On the
  217.       bright side, it appears that each listing is complete, although
  218.       I didn't try all of the listings.  
  219.  
  220.       ------------------------------------------------------------ 
  221.  
  222.       NOTE: Since writing the above, I have received a letter from Tim
  223.       Landgrave, the Product Manager for Technical Journals for the
  224.       Cobb Group, which was sent to all subscribers to "Inside Turbo
  225.       C".  Although it is a bit of an understatement, he admits that
  226.       there are problems with the first two issues of "Inside Turbo
  227.       C".  Although I didn't catch it (probably because I don't have
  228.       the book), one of the examples in the first issue is straight
  229.       out of the book "Turbo Algorithms".  Also, surprise, surprise,
  230.       the program listing for the pointer article is part of the
  231.       Borland Microcalc source code.  Well, because of these and other
  232.       mistakes, all subscriptions to "Inside Turbo C" will begin anew
  233.       with the November issue.  The first volume is considered trash
  234.       ("When your new issue arrives, please throw your old ones
  235.       away."), and the November issue will be volume II, number 1.
  236.       According to Tim, the upcoming issues "will be outstanding in
  237.       every way."  While that remains to be seen, a review of these
  238.  
  239.  
  240.       
  241.  
  242.  
  243.       Issue                        C News                             6
  244.  
  245.  
  246.       upcoming issues of "Inside Turbo C" will appear in an upcoming
  247.       issue of the "C News".  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.       
  301.  
  302.  
  303.       Issue                        C News                             7
  304.  
  305.  
  306.       ================================================================= 
  307.       BEGINNERS CORNER by Wayne Dernoncourt    
  308.       ================================================================= 
  309.  
  310.  
  311.  
  312.            In the last column I discussed how to use pointers with the
  313.       "standard" functions found in almost all implementations
  314.       currently in use.  This column is going to extend the discussion
  315.       of pointers with a discussion of just what pointers are and how
  316.       they operate.  
  317.  
  318.            Most computers operate with certain absolutes, that is,
  319.       there are things that will never change on a specific model or
  320.       brand of computer.  In the case of an IBM PC compatible
  321.       computers, the system clock is at a specific location in memory,
  322.       as are the keyboard buffer and disk drive status locations
  323.       (there are others, but this is not intended to be a
  324.       comprehensive list, just a few examples).  As a programmer you
  325.       will rarely, if ever, have to deal with these specific locations
  326.       -- there are operating system functions which you will use to
  327.       interact with these memory locations -- but they do exist.  
  328.  
  329.            You can imagine that even if you know the absolute address
  330.       of the memory location that you want to access, it would be
  331.       difficult to tell a compiler that whenever you access the
  332.       variable 'a', you want the computer to access a specific
  333.       location.  In C this is handled through the mechanisms of
  334.       pointers, that is a way for a variable to 'point' to something
  335.       else.  Since the addresses of the examples (the system clock,
  336.       keyboard buffer and disk drive status) are ones that never
  337.       change - you can use the C keyword "const" that says that these
  338.       addresses will never change and that an error is to be signaled
  339.       if your program ever tries to change the address. You can now
  340.       set a variable equal to the value pointed at by the pointer.  
  341.  
  342.            Let's go back to the example that we started using when
  343.       this series of articles first started off, that of finding the
  344.       average of 4 numbers.  Again we're only going to modify one
  345.       module, the one called GETDATA.  Everything else is going to
  346.       remain the same temporarily.  
  347.  
  348.       Here is the code as it was published in the second column of
  349.       this series: 
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.       
  361.  
  362.  
  363.       Issue                        C News                             8
  364.  
  365.  
  366.       /* GET_DATA.C */
  367.       /*   2. Get any quantity of numbers from a file.  To simplify the
  368.               problem, we will initially use four numbers hardcoded into 
  369.               the program.  As this column progresses, these 
  370.               simplifications will be removed. */
  371.  
  372.       float get_data()
  373.       {
  374.            float sum_x=0.0;
  375.  
  376.            sum_x += 1.0;   /* Start here*/
  377.            sum_x += 2.0;
  378.            sum_x += 3.0;
  379.            sum_x += 4.0;   /* End here*/
  380.  
  381.       /* Now is the time to return back to the main program. */
  382.            return(sum_x);
  383.       }
  384.  
  385.       The first order of business is to get rid of the restriction
  386.       that we placed at the top of the column.  We're going to read in
  387.       the four numbers from a file.  If there are less than four
  388.       numbers present, the program should do what?  If there are more
  389.       than four numbers, the extras will be ignored.  We'll use some
  390.       of the techniques developed in the last column on reading a
  391.       file.  (I've also modified the header at the top of the file,
  392.       initially we were going to read the keyboard, now we're using a
  393.       file.  The same principles apply in both cases.) 
  394.  
  395.            I'm going to map out what is going to take place first in
  396.       pseudo-code in an attempt to get you to develop good programming
  397.       habits.  
  398.  
  399.       Basic function declaration - describe what the function is supposed to do
  400.       Any #include statements that will be needed
  401.       Declare the function - include the pointer variable
  402.            Declare memory needed for the file
  403.            Declare the variables that be used, the total & the
  404.                 intermediate variable
  405.                 (passed from the calling routine)
  406.            Open the file for reading, check for error on opening
  407.            Setup a loop that will execute until a 'stop value' is
  408.                     encountered (in this case a negative number)
  409.                 Read in a number into an intermediate variable
  410.                 Add the intermediate variable to the total
  411.                 Increment the counter that indicates the number of
  412.                    samples read in
  413.            Terminate the loop
  414.            Decrement the counter (remember we incremented the counter
  415.                 before we checked the validity of the entry)
  416.            Subtract the 'stop value' from the total
  417.            Close the file
  418.  
  419.  
  420.       
  421.  
  422.  
  423.       Issue                        C News                             9
  424.  
  425.  
  426.       Return the sample size as a passed variable & the total in the
  427.            function call
  428.  
  429.       Now for the C code to implement this pseudocode: 
  430.  
  431.       /* GET_DATA.C */
  432.       /* Read in any quantity numbers from a file - stop on negative numbers */
  433.       /* Data passed to this function: address of the variable to hold the */
  434.       /* sample size */
  435.       /* Data returned from this function: The sum of the series of real */
  436.       /* numbers */
  437.  
  438.       #include  <stdio.h>
  439.  
  440.       float get_data(int *samp_size_ptr)
  441.       {
  442.          FILE *in_file;                       /* declare an area for a file */
  443.          float sum_x = 0.0;                   /* THIS WAS IN THE ABOVE CODE */
  444.          float in_val;                        /* declare an intermediate */
  445.                                               /* variable to be read in */
  446.  
  447.          if ((in_file = fopen ("mydata.dat", "r+t")) == NULL)
  448.          {
  449.             printf ("Oops, I don\'t see the data file\n");
  450.             exit(1);
  451.          }
  452.  
  453.          do {                       /* set up a loop to read in the file */
  454.             fscanf (in_file, "%f", &in_val);  /* read the file */
  455.             sum_x += in_val;                  /* add the value to the old sum */
  456.             (*samp_size_ptr)++;               /* increment the counter */
  457.                  }  while (in_val >= 0);
  458.  
  459.          (*samp_size_ptr)--;        /* we have to decrement this because */
  460.          sum_x -= in_val;           /* tried to read in the stop number */
  461.                                     /* and add in the stop number to the sum */
  462.  
  463.          fclose (in_file);          /* close the file */
  464.          return (sum_x);            /* return the sum to the main */
  465.                                     /* program */
  466.       }
  467.  
  468.            That's the new version of the GET_DATA routine.  There are
  469.       a number of unusual things in this function.  First is the
  470.       function declaration itself.  Notice that in the parentheses is
  471.       what looks like a variable declaration with an asterisk in front
  472.       of it.  That is how you declare a pointer.  In this specific
  473.       case, I've declared that the variable, samp_size_ptr, is in
  474.       reality a 'pointer' to a location in memory, and that this
  475.       memory location is to contain an integer. The next odd thing
  476.       that the keen eyed reader will spot is the backslash 't' in the
  477.       printf expression that will be printed if the data file couldn't
  478.  
  479.  
  480.       
  481.  
  482.  
  483.       Issue                        C News                            10
  484.  
  485.  
  486.       be opened.  There has to be way to put non-printing characters
  487.       into a string and it is done with escape sequences that begin
  488.       with the backslash.  An abbreviated list of these is included
  489.       below for quick reference: 
  490.  
  491.            Sequence  Action
  492.            \a        Audible bell - this is an ANSI extension
  493.            \b        Backspace
  494.            \f        Formfeed
  495.            \n        New line
  496.            \t        Horizontal tab
  497.            \'        Apostrophe or Single quote
  498.            \"        Double quote - this is an ANSI extension
  499.            \?        Question mark
  500.  
  501.       The next thing you might ask yourself is why don't we just use
  502.       the GET_DATA routine to get the data from the file and return
  503.       the value to the calling routine and let it (the calling
  504.       routine) decide what to do next (get more data, proceed with the
  505.       computations, etc.)?  That's logical (it modularizes the code,
  506.       etc.), but unfortunately it also defeats one of the main things
  507.       that I'm going to show you in the near future, so I'm going to
  508.       keep this slightly illogical organization.  
  509.  
  510.            You may also notice the '&' in the fscanf function call.
  511.       By the way, you may also have noticed that all of the function
  512.       oriented to files start with an 'f' (i.e. fopen, fscanf, fclose,
  513.       etc.), this is by design, not chance and is part of the ANSI
  514.       standard.  This symbol tells the compiler to generate
  515.       instructions to the computer to pass the address of the variable
  516.       to the function instead of the variable itself.  This
  517.       arrangement is termed "pass-by-reference".  
  518.  
  519.            The last thing that I hope you noticed actually consists of
  520.       two things, that of (*samp_size_ptr)++ and (*samp_size_ptr)--.
  521.       Let's dissect this example carefully to find out what is going
  522.       on.  First the statement [ *samp_size_ptr ] inside of the
  523.       parentheses is executed, this retrieves the value stored at that
  524.       location in memory.  Then that value is incremented (or
  525.       decremented as the case may be), and the value is stored back at
  526.       the same location in memory.  
  527.  
  528.       The main program file also changes (in three small ways):  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.       
  541.  
  542.  
  543.       Issue                        C News                            11
  544.  
  545.  
  546.       #include <stdio.h> 
  547.       float get_data (int *to_samp_size); /* <<--- this changed */ 
  548.       float compute (int samp_size, float x_sum); 
  549.       void print_results (float average);
  550.  
  551.       main ()
  552.  
  553.       /*   This program is to find the mean (average) and standard
  554.        deviation of a series of numbers.  The numbers will be read in
  555.        from the keyboard and printed on the screen.  Enter -1 when
  556.        finished.  Temporarily simplified and reading from a file instead */
  557.  
  558.       /* initialization of variables */
  559.       /* 1. Declare all variables needed and initialize them to zero.*/
  560.       {
  561.           int samp_size=0; /* samp_size: number of variables read in*/
  562.           float sum_of_x=0; /* this is the sum of the variables read in*/
  563.           float answer;
  564.  
  565.            /* get the data needed by the program */
  566.           sum_of_x = get_data(&samp_size);    /* <<--- this changed */
  567.  
  568.                                               /* <<--- deleted a line here */
  569.  
  570.            /* Now compute the answer */
  571.           answer = compute(samp_size, sum_of_x);
  572.  
  573.            /* Print the results out */
  574.           print_results (answer);
  575.  
  576.            /* Closing the brace on the main routine exits the
  577.            program.  There are other ways out, but this way will do for
  578.            now.*/
  579.       }
  580.  
  581.       As I said before, three things have changed in the main
  582.       program.  The first thing is that the function prototype now
  583.       contains a reference to a variable that I've called
  584.       'to_samp_size'.  Remember that name of the variable isn't
  585.       critical (as long as it makes sense to you and helps you
  586.       remember what the variable is for).  In this case the variable
  587.       is to receive an address.  The next thing is the '&' in my call
  588.       to the function called 'get_data'.  This means that I want to
  589.       pass not the variable, but the ADDRESS of the variable to the
  590.       function.  The next line, the line that used to set 'samp_size'
  591.       to a quantity is no longer needed.  
  592.  
  593.       The other three files (COMPUTE.C, PRINTRES.C & AVERAGE.PRJ) are
  594.       included here for completeness.  In the file called COMPUTE.C: 
  595.  
  596.  
  597.  
  598.  
  599.  
  600.       
  601.  
  602.  
  603.       Issue                        C News                            12
  604.  
  605.  
  606.       /* This is the function that determines the average of a bunch
  607.          of numbers */
  608.       float compute (int n, float xsum)
  609.       {
  610.           return (xsum/(float)n);
  611.       }
  612.  
  613.       In the file called PRINTRES.C: 
  614.  
  615.       /* This function prints out the average of the numbers that have
  616.          been entered or read in */
  617.       void print_results (float average)
  618.       {
  619.           printf ("\nThe average of the four numbers is:%f\n", average);
  620.           return;
  621.       }
  622.  
  623.       In the file called AVERAGE.PRJ: 
  624.  
  625.       average
  626.       get_data
  627.       compute
  628.       printres
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.       
  661.  
  662.  
  663.       Issue                        C News                            13
  664.  
  665.  
  666.       ================================================================= 
  667.       TOGGLES AND COMMAND-LINE PARSING by Paul E. Castle II
  668.       ================================================================= 
  669.  
  670.  
  671.  
  672.            Every beginners book on C starts out the same way.  It
  673.       teaches you how to print "Hello, world" on the screen.  From
  674.       that point on they all follow essentially the same path, the
  675.       only real difference being the author's ability to entertain and
  676.       teach at the same time.  These books teach the basics of the C
  677.       language and programming.  They give you something upon which to
  678.       build.  This education is extended and enhanced in the pages of
  679.       intermediate and advanced texts.  These texts cover topics that
  680.       range from random number generators, sort/search algorithms, and
  681.       linked lists to complete menuing systems and serial port I/O.  
  682.  
  683.            However, there seems to be a gap between the beginner and
  684.       intermediate texts, an area of routines and techniques slightly
  685.       beyond the beginner's needs and slightly beneath the needs of
  686.       the intermediate programmer.  
  687.  
  688.            One such case came to my attention while coding a video
  689.       tape library program (VTL from this point forward).  VTL is a
  690.       windowed application.  I thought that exploding windows (windows
  691.       that seem to explode from the center of the screen out) would be
  692.       a nice touch.  After a while, however, exploding windows can
  693.       cease being an exciting feature and become a distraction.  So, I
  694.       wanted to give users the ability to toggle the exploding windows
  695.       on and off.  
  696.  
  697.            I created an integer variable named "explode_active".  When
  698.       set to 0, exploding windows are inactive.  When set to 1, they
  699.       are activated.  I then added code that was executed whenever
  700.       [F10] was pressed.  
  701.  
  702.            My first effort was as follows: 
  703.  
  704.              if (explode_active == 0)  
  705.                explode_active = 1;
  706.              else  
  707.                explode_active = 0;
  708.  
  709.            This works.  It is simple and obvious.  But, I felt is was
  710.       more complicated than this simple function need be.  I realized
  711.       that I could change the "if" statement to read:
  712.       "if(!explode_active)" and produce the same result.  But there
  713.       had to be a better way.  I searched my library of C books (which
  714.       number in the dozens) and found nothing on toggles.  I left the
  715.       code as it was and went on to other things.  
  716.  
  717.            A few days later, a thought struck me.  If I "XOR" 0 and 1,
  718.  
  719.  
  720.       
  721.  
  722.  
  723.       Issue                        C News                            14
  724.  
  725.  
  726.       I get 1.  And, if I "XOR" 1 and 1, I get 0.  That was just the
  727.       operation I wanted for the toggle.  I rewrote the routine to be: 
  728.  
  729.              explode_active = explode_active ^ 1;
  730.  
  731.       Elegant, simple and not that obvious.  And not covered in the
  732.       texts.  So, the answer to how best deal with toggles is as
  733.       follows: 
  734.  
  735.             1.  Create an integer variable - toggle
  736.             2.  Assume 0 is off, 1 is on
  737.             3.  toggle = toggle ^ 1
  738.  
  739.       This is something that almost everyone will use and which slips
  740.       through the cracks between the beginner and intermediate books.
  741.       For another example, read on! 
  742.  
  743.            Jim Singleton recently wrote an article on passing and
  744.       accessing command line parameters.  I'd like to expand on that
  745.       article and talk about command line parsing, an important topic
  746.       that is neither as simple nor as obvious as toggles and is
  747.       rarely found in the texts.  
  748.  
  749.            Sooner or later you will want to pass parameters from the
  750.       command line to your program.  At first, it may be a simple file
  751.       name.  Later, a source and destination directory.  But,
  752.       eventually, you will want to use command line parameters as
  753.       configuration switches.  
  754.  
  755.            This was the case with VTL.  Look at the VTL command
  756.       syntax: 
  757.  
  758.                         VTL - Video Tape Library
  759.  
  760.                     VTL was written by Paul E. Castle II
  761.  
  762.                  Syntax:  VTL [-switches]
  763.  
  764.                           -b = BIOS screen writing
  765.                           -c = CGA snow elimination
  766.                           -h = Display VTL Syntax
  767.                           -m = Monochrome attributes forced
  768.                           -x = Exploding windows active
  769.  
  770.       As you can see, VTL can be configured at startup.  The command
  771.       to start VTL with exploding windows active, monochrome output,
  772.       and BIOS I/O would be: 
  773.  
  774.       VTL -x -m -b
  775.  
  776.  
  777.            Jim, in his article, told you how to process this command
  778.  
  779.  
  780.       
  781.  
  782.  
  783.       Issue                        C News                            15
  784.  
  785.  
  786.       line.  But, what happens when VTL is started in this manner:  
  787.  
  788.       VTL -xmb
  789.  
  790.            In the first case, argc indicates 4 parameters and argv
  791.       contains pointers to the path to VTL and the strings -x, -m, and
  792.       -b.  In the second, argc shows 2 parameters and argv contains
  793.       pointers to the path to VTL and the string -xmb.  To use the
  794.       second form, your program must be capable of parsing, or
  795.       separating out, the switches contained in the string -xmb.  
  796.  
  797.            Look at the code that follows: 
  798.  
  799.       parse_cmd_line(int argc,char *argv[])
  800.       {
  801.           register int i,j;
  802.           char *p;
  803.  
  804.           for(i = 1;i < argc;i++) {
  805.               p = argv[i];
  806.               if (*p == '-' || *p == '/') {
  807.                   for(j = 1;*(p+j);j++) {
  808.                       switch(tolower(*(p+j))) {
  809.                           case 'b':
  810.                               setvparam(VP_BIOS);
  811.                               break;
  812.                           case 'c':
  813.                               setvparam(VP_CGA);
  814.                               break;
  815.                           case 'm':
  816.                               setvparam(VP_MONO);
  817.                               break;
  818.                           case 'x':
  819.                               explode_active = YES;
  820.                               break;
  821.                           default:
  822.                               error_exit(2); }
  823.                   }
  824.               }
  825.           else 
  826.               error_exit(2); }
  827.       }
  828.  
  829.  
  830.            Notice that the function "parse_cmd_line" is invoked with
  831.       the calling function passing argc and argv.  This is the same
  832.       syntax as described in Jim's article.  Next, look at the "for"
  833.       statement: "i" is used as an index into argv, "argv[0]" is the
  834.       path to the executing program.  In this case, we are not
  835.       interested in argv[0] so "i" is set to 1.  This will be a
  836.       pointer to the first parameter (if any) on the command line.
  837.       "i<argc" controls the duration of the loop.  We will process the
  838.  
  839.  
  840.       
  841.  
  842.  
  843.       Issue                        C News                            16
  844.  
  845.  
  846.       command line as long as "i" is less than argc (remember, argc
  847.       will contain the number of command line parameters while the
  848.       array argv starts at 0.  If argc is 3, argv will have entries 0,
  849.       1, and 2).  And finally, "i" will be incremented with each
  850.       iteration.   
  851.  
  852.            The next line sets "p" to point to the string pointed to by
  853.       argv[i].  This means that, with each iteration of the "for"
  854.       loop, "p" will point to each successive command line parameter.
  855.       The "if" statement determines if the first character of the
  856.       string, pointed to by "p", is a switch character.  VTL allows
  857.       either the "-" or the "/" to be used as the switch character.  
  858.  
  859.            Now, skip down to the end of the "if" statement.  The
  860.       "else" statement is executed if a valid command line switch
  861.       character if not found.  In the case of VTL, "error_exit" is a
  862.       function to handle error conditions.  Based on the value passed,
  863.       "error_exit" prints out an error message and terminates
  864.       processing.  A value of 2, as in this case, will print out the
  865.       VTL syntax.  
  866.  
  867.            Back to the top.  The next statement establishes a second
  868.       loop.  The loop will be performed until the condition "*(p+j)"
  869.       is false.  This is the real key to parsing the command line.  
  870.  
  871.            Let's analyze this a little.  "p" is set to point to the
  872.       beginning of a string.  If our command line was "VTL -xm -b" and
  873.       "i" is equal to 1, "p" is pointing to the "-" in "-xm".  The
  874.       second loop (or internal loop) begins with "j" equal to 1.  This
  875.       means that "*(p+j)" is equal to "x".  The reason for this is
  876.       that "p" is a pointer to type character.  The (p+j) is resolved
  877.       by incrementing the address, held by "p", by one character
  878.       length, or one byte.  The "*" operator says to assume the value
  879.       of the address pointed to by "(p+j)".  This value is "x".
  880.       Therefore, the condition "*(p+j)" is true and the switch
  881.       statement is processed.  In this case, the value "x" triggers
  882.       the "case 'x'" and "explode_active" is set to "YES" (which is
  883.       defined as a value of 1).  Notice that the switch statement
  884.       changes the value pointed to by "(p+j)" to a lower case letter.
  885.       This allows the user to enter parameters in either upper case or
  886.       lower case.  
  887.  
  888.            Once the switch statement has completed, the for loop
  889.       cycles again.  This time "j" is incremented to 2.  In the
  890.       example above, "*(p+j)" will now resolve to "m".  The loop
  891.       cycles again, "j" is incremented to 3, and this time "*(p+j)"
  892.       resolves to the NUL char or '\0'.  This is because all strings,
  893.       in C, are terminated by a '\0' character.  The '\0' character
  894.       has the ASCII value 0, which equates to false.  The internal
  895.       loop completes and we return to the first loop and increment
  896.       "i".  On this next pass, "p" is pointing to the string "-b".
  897.       The "b" switch will be processed, as above, and we return to the
  898.  
  899.  
  900.       
  901.  
  902.  
  903.       Issue                        C News                            17
  904.  
  905.  
  906.       first loop.  This time "i" is set to 3, which is equal to argc,
  907.       and the function returns to the calling routine.  
  908.  
  909.            One final point.  Notice that the default "case" in the
  910.       switch statement is to execute "error_exit" with a value of 2.
  911.       Whenever an invalid parameter is encountered, the switch will
  912.       use the default and, in the case of VTL, display the VTL syntax
  913.       and terminate processing.  
  914.  
  915.            Command line parsing is a powerful and flexible tool in C
  916.       programming.  It is also one that is seldom found in the texts.
  917.       I hope this helps to fill the gap.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931.  
  932.  
  933.  
  934.  
  935.  
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942.  
  943.  
  944.  
  945.  
  946.  
  947.  
  948.  
  949.  
  950.  
  951.  
  952.  
  953.  
  954.  
  955.  
  956.  
  957.  
  958.  
  959.  
  960.       
  961.  
  962.  
  963.       Issue                        C News                            18
  964.  
  965.  
  966.       ================================================================= 
  967.       WHERE'S THAT NUMBER?: A PROJECT IN PROGRAMMING DESIGN 
  968.       ================================================================= 
  969.  
  970.  
  971.                               by Jim Singleton
  972.  
  973.            Back a number of issues ago, Barry and I started what was
  974.       to be a series of articles on programming design.  (See
  975.       "Programming Design: OpusGraf a Project, Part I", issue 13, page
  976.       12.)  We never finished that series, as noted in issue 14,
  977.       because Dan whipped out OpusGraf using AWK, as part of his AWK
  978.       introduction.  Well, here we go again.  (This time, I know Dan
  979.       is busy, so he will not jump in and finish this series
  980.       prematurely.) 
  981.  
  982.            This is going to be a series of articles dealing with
  983.       software development.  Here at the "C News", we have long
  984.       thought that a series on programming design would be helpful to
  985.       our readers.  While not everyone programs in the same style or
  986.       manner, most experienced programmers follow roughly the same
  987.       development process.  This programming project will follow a
  988.       project from the idea stage all the way through the design,
  989.       coding, and modification of the program.  While we will follow
  990.       the "correct" programming guidelines, remember that not everyone
  991.       writes their programs in the same way and what may be the right
  992.       way for one person is not always the right way for you.  
  993.  
  994.            For this series of articles, we will be dealing with a
  995.       program called PHONENUM, a short program which displays a phone
  996.       number for a name entered on the command line.  This first
  997.       article, will deal with the first six steps of software design: 
  998.  
  999.            1.  Defining the Problem
  1000.            2.  Defining the Solution
  1001.            3.  Mapping the Solution
  1002.            4.  Coding the Program
  1003.            5.  Debugging the Program
  1004.            6.  Documenting the Program
  1005.  
  1006.       The seventh (and final) step of software design is updating the
  1007.       program; which can be a never-ending process, as you think of
  1008.       things which can be improved.  It also involves several of the
  1009.       other steps.  Obviously, since we will just be writing PHONENUM
  1010.       in this article, we can't really update it just yet.   
  1011.  
  1012.  
  1013.  
  1014.  
  1015.  
  1016.  
  1017.  
  1018.  
  1019.  
  1020.       
  1021.  
  1022.  
  1023.       Issue                        C News                            19
  1024.  
  1025.  
  1026.  
  1027.       The Idea        
  1028.       (Also known, by the more textbook types, as "Defining the
  1029.       Problem") 
  1030.  
  1031.            The first part of any programming project is the idea for
  1032.       the program itself.  I don't know of any programmers who sit
  1033.       down and start writing code with no idea of what they will
  1034.       write.  Ideas for programs can strike anytime, anyplace.  For
  1035.       example, I write them down on a sheet/scrap of paper and then,
  1036.       at some point, copy the good ones into a loose leaf notebook.
  1037.       Barry is more organized than I am, he carries a Black
  1038.       Composition book -- the kind that you find in school bookstores
  1039.       -- and makes entries as needed.  At the end of week, he goes
  1040.       through the entries and makes a list of the ones that he wants
  1041.       to work on, and scratches out those that either he has no time
  1042.       for or were really "banana wackers".  
  1043.  
  1044.            How did I decide to write PHONENUM?  Recently, I had to
  1045.       call Barry, so I had to look up his phone number.  Of course, I
  1046.       had Barry's phone number on my computer; but, to look it up, I
  1047.       either had to install SideKick or otherwise list it out.  I had
  1048.       been meaning to organize them and write up a short program to
  1049.       display a phone number.  (Everyone knows someone, possibly even
  1050.       themselves, who keeps meaning to write a short little program to
  1051.       do something and keeps putting it off, right?)  So, I decided I
  1052.       would finally sit down and write this program and that I would
  1053.       use it to show the steps involved in developing a program from
  1054.       start to finish.  
  1055.  
  1056.            Once you decide that it's time to act on one of these
  1057.       ideas, what do you do? 
  1058.  
  1059.       The Solution        
  1060.       (Oops, let's be formal -- "Defining the Solution".) 
  1061.  
  1062.            Hey, the solution is simple, you say?  All I have to do is
  1063.       write a program look up a phone number.  Correct, but that's not
  1064.       all that goes into the solution.  How do I want it displayed?
  1065.       What should the program look like when it's running?  Do I want
  1066.       windows?  As you can see, there are a number of things which go
  1067.       into the solution of a programming problem.  
  1068.  
  1069.            Well, in the case of this program, PHONENUM, what do "I"
  1070.       want?  (See, this is the advantage of being the author, I can
  1071.       write the program exactly as I want it.)  I want to be able to
  1072.       call the program with a name as an argument on the command
  1073.       line.  Why?  I have a program which will display the location of
  1074.       area codes throughout the country that way, in addition to one
  1075.       that will display the location of local telephone exchanges, so
  1076.       why not one to display phone numbers of the people I deal with? 
  1077.  
  1078.  
  1079.  
  1080.       
  1081.  
  1082.  
  1083.       Issue                        C News                            20
  1084.  
  1085.  
  1086.            Basically, that's all that there is to the solution of this
  1087.       problem.  I want to be able to type: 
  1088.  
  1089.            PHONENUM lynch
  1090.  
  1091.       at the system prompt and have Barry's phone number displayed.  
  1092.  
  1093.            Wait a minute, how am I going to add phone numbers to the
  1094.       list I will be using?  Sure, I could maintain a text file with a
  1095.       text editor or even add a text editor into the program to
  1096.       maintain the list.  Okay, so I will have to have a way to add
  1097.       names and numbers to my list.  
  1098.  
  1099.            I guess, why I am at it, that I also need to have a warning
  1100.       displayed to the user if the wrong number of parameters is
  1101.       entered.  ("I" won't forget, but what if some else wants to use
  1102.       the finished program?) 
  1103.  
  1104.            There are a number of other things I could include in the
  1105.       finished program, many of which will be revealed as you read
  1106.       this article, but these three are the only ones necessary for
  1107.       the basic program.  (I am purposely making this program fairly
  1108.       basic, feel free to make modifications as you see fit.) 
  1109.  
  1110.       To recap, the solution to this problem contains the following
  1111.       parts: 
  1112.  
  1113.            Command-line interface.
  1114.            Warning for in correct number of parameters.
  1115.            Method to add names to the list.
  1116.  
  1117.       Mapping the Solution       
  1118.       (Also known by the dreaded term "flowchart".) 
  1119.  
  1120.            Okay, I know this section brings up the dreaded F-word.
  1121.       Come on, let's say it and get it over with.  Flowchart.  There,
  1122.       that wasn't too bad, was it? (You know, in this case, I like the
  1123.       textbook types term, "mapping the solution".) 
  1124.  
  1125.            As most people may have guessed, I don't particularly care
  1126.       for doing flowcharts.  Back when I was learning FORTRAN, I used
  1127.       to do the flowcharts after I had finished the program and i
  1128.       would not have done them if I had not been required to turn them
  1129.       in.  These days, however, I do find that mapping out the
  1130.       solution is a good idea.  I don't always map out the solution,
  1131.       because there are some programs that are straightforward and
  1132.       don't need it.  There are also times I only map out a part of a
  1133.       solution (normally, a more complex part).  
  1134.  
  1135.            One other thing I don't do anymore, is worry about what
  1136.       symbols I use.  Obviously, if I was preparing this as part of a
  1137.       class assignment or something, I would; but, for my own
  1138.  
  1139.  
  1140.       
  1141.  
  1142.  
  1143.       Issue                        C News                            21
  1144.  
  1145.  
  1146.       programs, boxes are all the symbols I need.  
  1147.  
  1148.       First, let's see an example of an unnecessary flowchart: 
  1149.  
  1150.                               +---------+
  1151.                               |  BEGIN  |
  1152.                               +---------+
  1153.                                    |
  1154.                                    |
  1155.                                    |
  1156.                          +--------------------+
  1157.                          |                    |
  1158.                          |      Display       |
  1159.                          |  "Hello, world."   |
  1160.                          |                    |
  1161.                          +--------------------+
  1162.                                    |
  1163.                                    |
  1164.                                    |
  1165.                               +---------+
  1166.                               |   END   |
  1167.                               +---------+
  1168.  
  1169.       Obviously, in the case of PHONENUM, our flowchart will be a
  1170.       little more complex.  The flowchart is rather self explanatory,
  1171.       and is contained in the accompanying file, PHONENUM.CHT.  (This
  1172.       way, if you don't want to look at it, you don't have to, just
  1173.       continue on to the next section.) 
  1174.  
  1175.       Coding the Program       
  1176.       (It's about time!!) 
  1177.  
  1178.            Well, we're finally to the point where we can begin coding
  1179.       the program.  Normally, this would be the section where you give
  1180.       serious consideration to the language you are going to use; but,
  1181.       since this is the C NEWS, we're going to do it in C.  
  1182.  
  1183.            Since this is not an article on how to write C programs, I
  1184.       am not going to go into depth about writing the code.  (If you
  1185.       are new to C, see Wayne's articles elsewhere in this issue,
  1186.       which will explain how to code in C.) 
  1187.  
  1188.            PHONENUM.C is written in TurboC, version 2.0, although it
  1189.       should compile with just about any C compiler with few
  1190.       modifications.  
  1191.  
  1192.            It is not the most elegant solution to our original
  1193.       problem, but it does work.  Why didn't I write a slick,
  1194.       whiz-bang piece of code?  For two reasons, one because I am just
  1195.       trying to illustrate the steps involved in program design, and
  1196.       because it gives us something to do in future articles, where we
  1197.       will enhance and refine the program.  (Future articles?  That's
  1198.  
  1199.  
  1200.       
  1201.  
  1202.  
  1203.       Issue                        C News                            22
  1204.  
  1205.  
  1206.       why "Part 1" included in the title.) 
  1207.  
  1208.       Debugging the Program       
  1209.       (Okay, I'll admit I don't write perfect programs the first time,
  1210.       but I'm not alone.) 
  1211.  
  1212.            Let's face it, we all make mistakes.  (That's why someone
  1213.       invented debuggers.)  When you first compile a program, you're
  1214.       going to find some mistakes.  Some will be little, such as a
  1215.       missing "}", while others will be harder to figure out.  While
  1216.       debuggers will solve a lot of problems, especially when it comes
  1217.       to missing "}"s, there are a lot of things they won't tell you.
  1218.       Among the hardest mistakes to find are mistakes in logic.  
  1219.  
  1220.            I find that once I have corrected syntax and pointer
  1221.       problems, that running different sets of test data will find
  1222.       errors.  In the case of our PHONENUM, looking up names that are
  1223.       not there, adding names and then looking them up, etc.  
  1224.  
  1225.            Once you have found all the errors you can find and then
  1226.       corrected them, it's time to beta test the program.  Someone
  1227.       other than yourself, may find problems you overlooked.  
  1228.  
  1229.            Well, there is a fairly large bug in PHONENUM.C (What,
  1230.       published code with a bug in it?!)  Can you find it?  Whoever
  1231.       mails me the best solution to this bug, by 01 May 1990, will get
  1232.       a free C NEWS coffee mug.  If more than one person sends in the
  1233.       same solution, a name will be selected out of a hat.  (In order
  1234.       to make it fair for our foreign readers, whose letters will take
  1235.       longer to reach us.)  All solutions must be sent through the
  1236.       mail, to: 
  1237.  
  1238.            Jim Singleton
  1239.            P. O. Box 15314
  1240.            Arlington, VA  22215
  1241.  
  1242.       No electronic replies, whether in the C Echo, GEnie, etc. will
  1243.       be eligible.  
  1244.  
  1245.       Documenting the Program       
  1246.       (Oh no, the dreaded "D" word!) 
  1247.  
  1248.            One of the most neglected parts of programming, if not the
  1249.       most neglected part, is adequately documenting the program. (I
  1250.       know, you'd rather be writing code.)  Adequate documentation is
  1251.       also one of the most important parts of programming, which is
  1252.       why it seems strange that it is so often neglected. Perhaps it
  1253.       is because most programmers would rather just program, rather
  1254.       than "waste" time documenting the program. (Hey, didn't I
  1255.       already say this?)  Failure to provide proper documentation is
  1256.       one of the worst habits a programmer can fall into.  
  1257.  
  1258.  
  1259.  
  1260.       
  1261.  
  1262.  
  1263.       Issue                        C News                            23
  1264.  
  1265.  
  1266.       Proper documentation consists of three parts: 
  1267.  
  1268.            1)  the program listing,
  1269.            2)  the technical manual, and
  1270.            3)  the user's manual.
  1271.  
  1272.       All three of these parts are important and none should be
  1273.       neglected.  
  1274.  
  1275.            The program listing is just that -- a listing of the
  1276.       program (which is why we call it a program listing).  This
  1277.       listing should include all the modules, sub-programs, etc. which
  1278.       make up the program.  Everything in the listing should be well
  1279.       commented.  Many programmers have a tendency to comment their
  1280.       programs rather sparsely, if at all, often because they add the
  1281.       comments after the program has been completed. The comments
  1282.       should be included as the program is being written.  This
  1283.       increases the actual time spent coding in the program, but it
  1284.       saves time later (trust me).  It is important to remember, that
  1285.       each time the program is updated, the comments should be
  1286.       updated.  (If you have ever had to update a piece of uncommented
  1287.       code, years later, you realize how important it is to add
  1288.       comments.) You don't have to comment each and every line of
  1289.       code, just what would not be self explanatory to someone else
  1290.       reading your code.  (Such things as 
  1291.  
  1292.            int count;
  1293.  
  1294.            or
  1295.  
  1296.            count++;
  1297.  
  1298.       are self-explanatory.) 
  1299.  
  1300.            The technical manual should describe the functions and
  1301.       purposes for each part of the program.  It serves as a detailed
  1302.       description of the program and how the program operates.  The
  1303.       technical manual should be written so that it will be useful
  1304.       should the program ever have to be modified or updated.  If the
  1305.       programmer prepared a flow chart prior to coding, each part of
  1306.       the flow chart could serve as a separate section of the
  1307.       technical manual.  The technical manual should contain the
  1308.       information the programmer used when the program was designed
  1309.       and coded.  Often, the technical manual will be what you have
  1310.       written down while you have been working on a program (my loose
  1311.       leaf notebook or Barry's notebook).  
  1312.  
  1313.            Lastly, the users manual describes the operation of the
  1314.       program from the perspective of the user.  This is what most
  1315.       programmers consider, along with comments embedded in the
  1316.       program, to be documentation.  While this is often the only part
  1317.       of the documentation which the programmer prepares, it is often
  1318.  
  1319.  
  1320.       
  1321.  
  1322.  
  1323.       Issue                        C News                            24
  1324.  
  1325.  
  1326.       of rather poor quality.  The user's manual should guide the user
  1327.       through the operation of the program, describing how it works
  1328.       and what is required of the user.  It should also include sample
  1329.       sessions or examples, whichever is more appropriate, of the
  1330.       program in operation.  As the user will refer to the users
  1331.       manual to learn how to use the program, in the case of problems,
  1332.       and with questions concerning the capabilities of the program,
  1333.       the users manual should anticipate as many potential questions
  1334.       and problem areas as possible and address them.  
  1335.  
  1336.            Why spend the time documenting a program?  If the program
  1337.       is for use by others, good documentation can prevent a lot of
  1338.       questions as to why something doesn't work.  If the program
  1339.       needs to be updated at a future date, good documentation makes
  1340.       the process a lot easier, whether you do it yourself or have
  1341.       some one else do it.  It can get very frustrating trying to
  1342.       figure out how a program without comments is supposed to
  1343.       operate.  What if it is only a short program, a utility composed
  1344.       of only a few lines of code, does it still need all three parts
  1345.       of the documentation?  Of course it does.  The technical and
  1346.       user's manuals may only be a page or so in length, but the
  1347.       documentation serves the same purpose as it would for a longer
  1348.       program--it tells how the program operates, how it was written,
  1349.       why it was written, how to use it, and what each part of the
  1350.       code does.  Proper documentation, a habit for every good
  1351.       programmer.  
  1352.  
  1353.            Okay, so what does the documentation for PHONENUM look
  1354.       like? Well, the code is commented, that's one-third of the
  1355.       documentation out of the way.  The technical documentation is
  1356.       what was written in my notebook (which is essentially in this
  1357.       article) and the flowchart.  Since this program was written for
  1358.       my own use, there really isn't any need for a users manual.
  1359.       However, if I were to distribute this program to anyone, I would
  1360.       write up a short READ.ME file, which would explain how it
  1361.       works.  
  1362.  
  1363.       Updating the Program.       
  1364.  
  1365.            After you have been using a program for a while, certain
  1366.       improvements will need to be made, parameters may change, etc.
  1367.       There may even be an error in the program that escaped detection
  1368.       earlier.  Updating the program is actually a never ending
  1369.       process, unless the program is either very simple or intended
  1370.       for limited use.  This is where the time spent commenting the
  1371.       code and writing the documentation comes in handy, because you
  1372.       won't be spending all your time trying to figure out what each
  1373.       line of code is supposed to do.  
  1374.  
  1375.            Since we just finished PHONENUM, there really isn't
  1376.       anything to do in the way of updating it, right?  Well....  When
  1377.       I was writing PHONENUM, I began to think of ways to make it more
  1378.  
  1379.  
  1380.       
  1381.  
  1382.  
  1383.       Issue                        C News                            25
  1384.  
  1385.  
  1386.       useful, so subsequent articles in this series will cover adding
  1387.       a help system to the program, adding a sort routine, adding a
  1388.       delete utility, windows, and perhaps making PHONENUM a TSR.
  1389.       (See?  I told you they would be revealed before the end of the
  1390.       program.)  If you have an idea on how you'd like to see any of
  1391.       these implemented or have an idea for a modification I haven't
  1392.       mentioned, please feel free to contact me here at the C News.  
  1393.  
  1394.  
  1395.  
  1396.  
  1397.  
  1398.  
  1399.  
  1400.  
  1401.  
  1402.  
  1403.  
  1404.  
  1405.  
  1406.  
  1407.  
  1408.  
  1409.  
  1410.  
  1411.  
  1412.  
  1413.  
  1414.  
  1415.  
  1416.  
  1417.  
  1418.  
  1419.  
  1420.  
  1421.  
  1422.  
  1423.  
  1424.  
  1425.  
  1426.  
  1427.  
  1428.  
  1429.  
  1430.  
  1431.  
  1432.  
  1433.  
  1434.  
  1435.  
  1436.  
  1437.  
  1438.  
  1439.  
  1440.       
  1441.  
  1442.  
  1443.       Issue                        C News                            26
  1444.  
  1445.  
  1446.       ================================================================= 
  1447.       SORTING PART 1 by Wayne Dernoncourt   
  1448.       ================================================================= 
  1449.  
  1450.  
  1451.  
  1452.       Introduction         
  1453.  
  1454.            The assignment: Write a sort program that will accept
  1455.       larger files than the MS-DOS sort program.  
  1456.  
  1457.            What an assignment!  That has to loose ends to it, so I'm
  1458.       going to impose some constraints on it.  
  1459.  
  1460.            1. You must be able to use the sort package multiple times
  1461.            to give the effect of multiple keys, i.e. you want to sort
  1462.            on the area-code & then sorted on the zip code, but you
  1463.            want the major sort to be on area-code but sub- sorted by
  1464.            zip code. [This eliminates some sort algorithms] 
  1465.  
  1466.            2. The sorts will be limited to sorting ASCII data, i.e.
  1467.            the sort will work on *ANY* file, but will work as if all
  1468.            of the data is ASCII.  Integer and floating point numbers
  1469.            which are multiple bytes will be interpreted (usually
  1470.            incorrectly) as ASCII data.  EXE and other binary files
  1471.            won't make any sense for sorting.  
  1472.  
  1473.  
  1474.       General design considerations       
  1475.  
  1476.            Since the assignment was to write a program to handle
  1477.       larger files than the DOS sort program can handle, let's use the
  1478.       disk to open some temporary files (this is supposed to handle
  1479.       LARGE files, but it may not be particularly fast).  
  1480.  
  1481.            How is this going to work, we'll actually sort the keys in
  1482.       memory using a linked list with references back to a temporary
  1483.       direct access file.  
  1484.  
  1485.            Let's write some pseudo-code to document how this is
  1486.       supposed to work: 
  1487.  
  1488.            Open the file to be sorted and find the length of the
  1489.            longest record (length_longest) and the number of records
  1490.            (num_of_recs) 
  1491.  
  1492.            Find out how much temporary storage space will be needed in
  1493.            memory: 
  1494.                 mem_needed = (size of key + 4 bytes + 4 bytes + 4
  1495.                 bytes) * num_of_recs 
  1496.  
  1497.            Find out if the amount of storage required is available
  1498.  
  1499.  
  1500.       
  1501.  
  1502.  
  1503.       Issue                        C News                            27
  1504.  
  1505.  
  1506.            from the heap? If not complain loudly and abort!! 
  1507.  
  1508.            Find out enough temporary file space is available
  1509.            disk_needed = length_longest * num_of_recs 
  1510.  
  1511.            If disk_needed is less than that available, complain loudly
  1512.            and abort!! 
  1513.  
  1514.            Open the file and allocate all of the space needed for the
  1515.            temporary file.  
  1516.  
  1517.            Everything is okay up too here, should we find out if there
  1518.            is enough space left over for the new file or just write
  1519.            over the old one??  No, we have to ask the user if there
  1520.            isn't enough room left over after we open the random access
  1521.            file.  
  1522.  
  1523.            Read in the source file sequentially into the temporary
  1524.            direct access file, copy the key into the corresponding
  1525.            memory location.  Copy the record number into the first 2
  1526.            four byte locations reserved (direct access record
  1527.            location, current position of key in list) and the record
  1528.            number+1 into the last four byte location (position of next
  1529.            record in list).  On the last record, enter a zero for the
  1530.            next location.  
  1531.  
  1532.            Use a bubble-sort on the key's rearranging only the linked
  1533.            list items.  Since the keys themselves don't change, we can
  1534.            get rid of the first four byte location that refers to the
  1535.            direct access record location, it's the same as the
  1536.            location in the array.  
  1537.  
  1538.            Go back through the linked list in memory and write the new
  1539.            file using the linked list and the direct access to get the
  1540.            entire record.  
  1541.  
  1542.            The reason for the bubble-sort is that to implement
  1543.       secondary keys, the plan is to have the user sort the data using
  1544.       this package from the deeper keys out (i.e.
  1545.       tertiarary/secondary/primary, etc.), so we can't rearrange the
  1546.       relationship that two records that have otherwise equivalent
  1547.       keys have to one another.  
  1548.  
  1549.  
  1550.  
  1551.  
  1552.  
  1553.  
  1554.  
  1555.  
  1556.  
  1557.  
  1558.  
  1559.  
  1560.       
  1561.  
  1562.  
  1563.       Issue                        C News                            28
  1564.  
  1565.  
  1566.       ================================================================= 
  1567.       C TUTORS: SHAREWARE AND PUBLIC DOMAIN by Jim Singleton
  1568.       ================================================================= 
  1569.  
  1570.  
  1571.  
  1572.            "Does anyone know of a shareware or public domain C
  1573.       tutor?"  How often have you been asked that question or seen it
  1574.       asked in the FidoNet C Echo?  I know I've heard/seen it more
  1575.       times than I can remember.  
  1576.  
  1577.            The last time I saw that question, I decided to take a look
  1578.       at what C tutors were available in the public domain and
  1579.       shareware arenas.  Unlike a compiler review, there will be no
  1580.       benchmarks with this article.  The only test I could think of
  1581.       was having a number of neophytes to C try each one and see which
  1582.       ones learned C the best, but I didn't feel like waiting for the
  1583.       results.  (Besides, how could I be sure some one wouldn't sneak
  1584.       out and read a book on me?) 
  1585.  
  1586.       CORONADO ENTERPRISES C TUTOR (Shareware)     
  1587.  
  1588.            This is probably the C tutor which is the most wide spread
  1589.       on BBS's around the country, usually in two files, C-TUTOR1.ZIP
  1590.       and C-TUTOR2.ZIP.  This tutor consists of a 14 chapter text and
  1591.       example files.  The text introduces C topics by stepping through
  1592.       these example programs as much as possible.  In addition to the
  1593.       basic topics one would expect to find in such an introductory
  1594.       tutorial, there is also coverage of such topics as dynamic
  1595.       allocation and bit manipulation.  Because of the differences
  1596.       between C compilers, a variety of different C compilers are
  1597.       supported, including Power C, Microsoft C, and TurboC.  (This
  1598.       tutorial can also be found on some BBS' as TCTUTOR1.ZIP and
  1599.       TCTUTOR2.ZIP.) 
  1600.  
  1601.       TUTOR_C.DOC (Public Domain)       
  1602.  
  1603.            This file, which is normally listed as CTUTOR.ZIP or
  1604.       TUTOR_C.ZIP, is a text file written by Brian Kernighan.
  1605.       (Usually this fact is mentioned in the file's description.)
  1606.       Essentially, this is a condensed version of K&R.  There are no
  1607.       example files, such as those included with the Coronado tutor,
  1608.       but there are examples in the text itself.  If I said you
  1609.       couldn't learn C from this file, I know some one would prove me
  1610.       wrong, but I doubt most beginners would get much out of it.  
  1611.  
  1612.       ADVENTURES IN C (Shareware)      
  1613.  
  1614.            This program, normally found as ADV_IN_C.ZIP, is a good
  1615.       tutorial except that it is not really interactive.  It does a
  1616.       good job of presenting the different topics it covers, but you
  1617.       don't need a compiler to use the program and there are no sample
  1618.  
  1619.  
  1620.       
  1621.  
  1622.  
  1623.       Issue                        C News                            29
  1624.  
  1625.  
  1626.       files included.  
  1627.  
  1628.       Teach-C (Shareware?)        
  1629.  
  1630.            Usually found as TEACH-C.ZIP, Teach-C is an interactive C
  1631.       tutorial somewhat like Adventures in C.  Unlike the latter
  1632.       tutorial, TEACH-C forces the user to go answer questions while
  1633.       going through the tutorial.  Written by P. J. Ponzo, of the
  1634.       University of Waterloo, Ontario, Canada, this tutorial uses his
  1635.       PonzoTUTOR system, which allows the user to interact with the
  1636.       program. (Instructions are also included to write your own
  1637.       tutorials using the PonzoTUTOR DISPLAY program.)  Halfway
  1638.       through and at the completion of the tutorial, there is a
  1639.       comprehensive test for the user.  I have also seen this tutorial
  1640.       as C-TC-RUN.ZIP, which has Turbo C versions of all the examples
  1641.       included.  
  1642.  
  1643.            So, which tutor is the best?  Whichever one teaches you C!
  1644.       Seriously, it really depends on your experience.  If you are
  1645.       coming to C cold, having just bought a compiler (without a good
  1646.       tutorial) and no other C books, the Coronado Enterprises tutor
  1647.       is probably the one for you.  The text file by Brian Kernighan
  1648.       is really only suited to those who need a quick little reference
  1649.       and don't have K&R.  Teach-C and Adventures in C are good for an
  1650.       introduction before using the Coronado Enterprises tutorial.
  1651.       Actually, Teach-C is a good review if you are taking a class in
  1652.       C, as it presents the topics in a very clear manner.  Ranked in
  1653.       order, with the best at the top, these tutorials end up as: 
  1654.  
  1655.            Coronado Enterprises C Tutor
  1656.            Teach-C
  1657.            Adventures in C
  1658.            Tutor_C
  1659.  
  1660.       Whichever one you choose, remember that actually keying in code
  1661.       and studying other programmer's code is one of the best ways to
  1662.       learn C.  (That's what puts the Coronado Enterprises C tutor far
  1663.       ahead of the rest of the ones reviewed here.) 
  1664.  
  1665.  
  1666.  
  1667.  
  1668.  
  1669.  
  1670.  
  1671.  
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.  
  1678.  
  1679.  
  1680.       
  1681.  
  1682.  
  1683.       Issue                        C News                            30
  1684.  
  1685.  
  1686.       ================================================================= 
  1687.       MIGRATING FROM C TO C++ by Roy Browning 
  1688.       ================================================================= 
  1689.  
  1690.  
  1691.  
  1692.       [Editor's Note: Roy Browning dropped off an article a few weeks
  1693.       ago on C++ programming here at the C BBS, for possible inclusion
  1694.       in an issue of C News.  Needless to say we were ecstatic, and
  1695.       look forward to more installments.  While I cannot claim Roy as
  1696.       the C News "C++ Columnist", I can send him a C News "Author"
  1697.       T-shirt and a coffee mug.  Thanks for the support Roy!] 
  1698.  
  1699.            When attempting to acquire new programming skills it is
  1700.       often expedient to write simple programs that will explore
  1701.       knowledge recently garnered.  The software presented here
  1702.       exhibits neither a good structured nor object oriented
  1703.       approach.  This is transition code that will hopefully achieve
  1704.       an acceptable object oriented design when this series is
  1705.       concluded.  
  1706.  
  1707.            The demonstration code enclosed is a very simple Directory
  1708.       Lister.  A familiar task to most programmers thus new techniques
  1709.       should readily be distinguishable from the known.  A program
  1710.       that details a couple of C++ techniques while retaining some
  1711.       misconceptions, a starting place for further exploration.  
  1712.  
  1713.       Classes and Functions       
  1714.  
  1715.       class FileList 
  1716.  
  1717.                 A simple class is created to encapsulate the data
  1718.            obtained from the familiar Dos findfirst/findnext function
  1719.            calls.  The number of files found and structure pointers
  1720.            are stored as "private" data.  The public members included
  1721.            are the constructor/destructor, a method to return a
  1722.            specific entry, a member to return the file count, and a
  1723.            print member to enable the information to be displayed.  A
  1724.            method to return an indexed subgroup of FileNames matching
  1725.            a passed string has been added.  
  1726.  
  1727.       FileList::FileList() 
  1728.  
  1729.                 The constructor has default arguments that can be
  1730.            superseded if supplied when the instance is created.  Dos
  1731.            interrupt calls are used and storage is dynamically
  1732.            allocated with the pointer array being reallocated once the
  1733.            number of files has been determined.   
  1734.  
  1735.  
  1736.  
  1737.  
  1738.  
  1739.  
  1740.       
  1741.  
  1742.  
  1743.       Issue                        C News                            31
  1744.  
  1745.  
  1746.       FileList::~FileList() 
  1747.  
  1748.                 The destructor should be self evident and is called
  1749.            whenever an instance of a class goes out of "scope".
  1750.            "Scope" commonly referring to a return from a function in
  1751.            which the instance was created or when the program is
  1752.            terminated.  
  1753.  
  1754.       FileList::Print() 
  1755.  
  1756.                 Prints information contained in the directory list.  A
  1757.            "for" loop is initialized with the number of files to
  1758.            display.  "form()" is used extensively to properly format
  1759.            the displayed files.  
  1760.  
  1761.       class FileDate
  1762.       class FileExt
  1763.       class FileName
  1764.       class FileSize
  1765.  
  1766.                 "Classes" that are derived from FileList with full
  1767.            access to the protected data and the public members.  The
  1768.            syntax that institutes a FileList is in the first line of
  1769.            the constructor declaration, remarkably powerful.  The
  1770.            sorting methods are invoked whenever an instance of the
  1771.            class is created.  
  1772.  
  1773.       FileDate::FileDate()
  1774.       FileExt ::FileExt()
  1775.       FileName::FileName()
  1776.       FileSize::FileSize()
  1777.  
  1778.                 This constructor supplies arguments to the FileList
  1779.            constructor via either the passed data or its own defaults
  1780.            when the instance is created.  Then the appropriate compare
  1781.            function is passed to "qsort()" creating a directory
  1782.            listing properly ordered.  
  1783.  
  1784.       FileDate::~FileDate()
  1785.       FileExt ::~FileExt()
  1786.       FileName::~FileName()
  1787.       FileSize::~FileSize()
  1788.  
  1789.                 The destructor is a dummy member relying on the
  1790.            FileList destructor to do the necessary clean up whenever
  1791.            the class goes out of scope.  
  1792.  
  1793.  
  1794.  
  1795.  
  1796.  
  1797.  
  1798.  
  1799.  
  1800.       
  1801.  
  1802.  
  1803.       Issue                        C News                            32
  1804.  
  1805.  
  1806.       Cmp_FileName()
  1807.       Cmp_FileExt()
  1808.       Cmp_FileDate()
  1809.       Cmp_FileSize()
  1810.  
  1811.                 These are simple compare functions that are passed to
  1812.            the "qsort()" function.  Numerical file names are properly
  1813.            sorted and they will default to a sort by name if all other
  1814.            data is equivalent.  It is imperative that they are
  1815.            declared as using the "C" calling convention (cdecl) or
  1816.            else a mangling error will be generated by the compiler.  
  1817.  
  1818.       First_Object()
  1819.       Second_Object()
  1820.       Third_Object()
  1821.       Fourth_Object()
  1822.  
  1823.                 These are test functions that create instances of
  1824.            class FileList passing the different Sort methods.  They
  1825.            are constructed as separate functions so the destructor
  1826.            will be called on return.  Otherwise memory would quickly
  1827.            become exhausted (64k) with large directory listings.  
  1828.  
  1829.       main() 
  1830.  
  1831.                 Calls the four test functions then creates an instance
  1832.            of FileSize.  Tests the FileName_Match member and displays
  1833.            all the matching directory entries.  Then selects a
  1834.            specific element in the directory array and displays the
  1835.            file's name.  Reports the total number of files matching
  1836.            the attributes, prints a final message and terminates.  
  1837.  
  1838.            This documentation is intentionally terse for the source
  1839.       code itself is the best example of the logic followed.  If you
  1840.       wish to supply alternative demonstrations you may contact me via
  1841.       the following means: 
  1842.  
  1843.                      Roy Browning
  1844.  
  1845.                      FidoNet             1:106/506
  1846.                      MCI Mail            184-6847
  1847.                      The Fulcrum's Edge  (713)350-6284
  1848.  
  1849.  
  1850.  
  1851.  
  1852.  
  1853.  
  1854.  
  1855.  
  1856.  
  1857.  
  1858.  
  1859.  
  1860.       
  1861.  
  1862.  
  1863.       Issue                        C News                            33
  1864.  
  1865.  
  1866.       ================================================================= 
  1867.       ARTICLE SUBMISSION STANDARDS      
  1868.       ================================================================= 
  1869.  
  1870.  
  1871.  
  1872.            All articles, reviews and letters to editor should be
  1873.       submitted as ASCII files.  Please do not format the text in any
  1874.       way (no hyphenation, justification, indentation, etc.) since we
  1875.       use Proff to format C News.  Proff takes care of the
  1876.       justification, footnotes and headers.  
  1877.  
  1878.            You can send in your article on a diskette to the C BBS, or
  1879.       upload it to the C BBS. See "How to Contact us here at C News"
  1880.       for more information.   
  1881.  
  1882.       Barry 
  1883.  
  1884.  
  1885.  
  1886.  
  1887.  
  1888.  
  1889.  
  1890.  
  1891.  
  1892.  
  1893.  
  1894.  
  1895.  
  1896.  
  1897.  
  1898.  
  1899.  
  1900.  
  1901.  
  1902.  
  1903.  
  1904.  
  1905.  
  1906.  
  1907.  
  1908.  
  1909.  
  1910.  
  1911.  
  1912.  
  1913.  
  1914.  
  1915.  
  1916.  
  1917.  
  1918.  
  1919.  
  1920.       
  1921.  
  1922.  
  1923.       Issue                        C News                            34
  1924.  
  1925.  
  1926.       ================================================================= 
  1927.       HOW TO GET HOLD OF US HERE AT CNEWS
  1928.       ================================================================= 
  1929.  
  1930.  
  1931.  
  1932.            The primary address for C News is as follows: 
  1933.  
  1934.            C News
  1935.            % BCL Limited
  1936.            P.O. Box 9162
  1937.            McLean, VA 22102
  1938.            USA
  1939.  
  1940.            The primary electronic address for C News is the C BBS: 
  1941.  
  1942.            C BBS
  1943.            1-703-644-6478
  1944.            2400,8,N,1 23hrs a day.
  1945.            1:109/307 in Fidonet.
  1946.  
  1947.            The secondary electronic address for C News is: 
  1948.  
  1949.            MCI Mail: BCL Limited
  1950.  
  1951.  
  1952.            Barry 
  1953.  
  1954.  
  1955.  
  1956.  
  1957.  
  1958.  
  1959.  
  1960.  
  1961.  
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.  
  1978.  
  1979.  
  1980.       
  1981.  
  1982.  
  1983.       Issue                        C News                             1
  1984.  
  1985.  
  1986.       *--------------------------------------------------------------*
  1987.       |    C NEWS - International C Electronic Newsletter/Journal    |
  1988.       |           "Dedicated to the Art of C Programming"            |
  1989.       |                                                              |
  1990.       |                      Founded 12/27/87                        |
  1991.       *--------------------------------------------------------------*
  1992.  
  1993.  
  1994.                               Table of Contents
  1995.  
  1996.       THE HEAP by Barry Lynch    ................................    2
  1997.  
  1998.       MAGAZINE REVIEW - INSIDE TURBO C by Jim Singleton..........    4
  1999.  
  2000.       BEGINNERS CORNER by Wayne Dernoncourt    ..................    7
  2001.  
  2002.       TOGGLES AND COMMAND-LINE PARSING by Paul E. Castle II......   13
  2003.  
  2004.       WHERE'S THAT NUMBER?: A PROJECT IN PROGRAMMING DESIGN .....   18
  2005.  
  2006.       SORTING PART 1 by Wayne Dernoncourt   .....................   26
  2007.  
  2008.       C TUTORS: SHAREWARE AND PUBLIC DOMAIN by Jim Singleton.....   28
  2009.  
  2010.       MIGRATING FROM C TO C++ by Roy Browning ...................   30
  2011.  
  2012.       ARTICLE SUBMISSION STANDARDS      .........................   33
  2013.  
  2014.       HOW TO GET HOLD OF US HERE AT CNEWS........................   34
  2015.  
  2016.  
  2017.  
  2018.       "C  News"  is  an  Electronic  Journal published by the C BBS in
  2019.       Burke,  VA  on  a monthly basis. The subject for C News is the C
  2020.       programming language, as well as any derivatives like C++.  
  2021.  
  2022.       All  readers  are  encouraged  to  submit  articles, reviews, or
  2023.       comments  for submission.  C News is freely distributed, but can
  2024.       not  be  sold  for a profit, or cannot have a charge assessed to
  2025.       cover  distribution costs.  All articles, and reviews become the
  2026.       property   of   C   News   and   cannot  be  included  in  other
  2027.       publications   without   written  permission  from  the  C  News
  2028.       Editorial  Staff.  To do so is in direct violation of the C News
  2029.       License  agreement.   Copies  of  which are available from the C
  2030.       BBS.    This  publication  is  Copyrighted  under  U.S. Copyright
  2031.       Law.
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.       
  2041.  
  2042.