home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / busi / nojcb.zip / CB.C next >
Text File  |  1989-09-09  |  36KB  |  780 lines

  1. /*----------------------------------------------------------------------------
  2.  *  File:     CB.C  (in Turbo C 1.5)
  3.  *
  4.  *  Purpose:  Checkbook program for the Ratzlaff family.  Reads the account
  5.  *            file into a linear, singly linked list and performs all trans-
  6.  *            actions in memory.  Writes changes to the file.
  7.  *
  8.  *  Author:   Steven "Noji" Ratzlaff
  9.  *
  10.  *  Date:     09 Sep 1989
  11.  *
  12.  *  Note:     This source code must be compiled with the compact memory model
  13.  *            and should be compiled in 80286 code.
  14.  *--------------------------------------------------------------------------*/
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <process.h>
  19. #include <math.h>
  20. #include <errno.h>
  21. #include <conio.h>
  22. #include <ctype.h>
  23. #include <alloc.h>
  24. #include <dir.h>
  25. #include <dos.h>
  26. /*--------------------------------------------------------------------------*/
  27. #define       CB_DIR         "C:\\CB\\"
  28. #define       DELIM          ':'
  29. #define       MAX_LINE      90
  30. #define       LINE_LIM      38
  31. #define       MSG_LEN       50
  32. #define       MAX_PATH      40
  33. #define       INPUT_SP      20
  34. #define       CURSOR        12
  35. #define       DEC           10
  36. #define       ELEMENTS       4
  37. #define       TRUE           1
  38. #define       FALSE          0
  39. /*------------ Key Values for get_char() -----------------------------------*/
  40. #define       BS             8
  41. #define       RET           13
  42. #define       ESC           27
  43. #define       SP            32
  44. #define       F1           187
  45. #define       F2           188
  46. #define       F3           189
  47. #define       F4           190
  48. #define       F5           191
  49. #define       F6           192
  50. #define       F7           193
  51. #define       F8           194
  52. #define       F9           195
  53. #define       F10          196
  54. #define       HOME         199
  55. #define       UP           200
  56. #define       PGUP         201
  57. #define       LEFT         203
  58. #define       RGT          205
  59. #define       END          207
  60. #define       DN           208
  61. #define       PGDN         209
  62. #define       DEL          211
  63. /*--------------------------------------------------------------------------*/
  64.   int         before_date(),           /* determines the place of a date    */
  65.               index = 0,               /* index number of the last record   */
  66.               get_char(),              /* gets a keyboard character         */
  67.               read_string();           /* reads a string from the keyboard  */
  68.   char        beg_bal[INPUT_SP],       /* beginning account balance         */
  69.               last_check[INPUT_SP],    /* the last check number             */
  70.               *prompt;                 /* the prompt from the environment   */
  71.   void        transact(),              /* calls all transaction routines    */
  72.               balance(),               /* balances the checkbook            */
  73.               clear_line(),            /* clears to the end of the line     */
  74.               date_format(),           /* formats the date to standard form */
  75.               directory(),             /* displays the account directory    */
  76.               enter_data(),            /* enters data from user to the list */
  77.               get_todays_date(),       /* grabs and formats today's date    */
  78.               get_cursor(),            /* retrieves the cursor position     */
  79.               increment_date(),        /* increments the date string        */
  80.               instructions(),          /* displays program instructions     */
  81.               list(),                  /* displays the list contents        */
  82.               make_change(),           /* allows user to change the list    */
  83.               num_format(),            /* formats a floating point string   */
  84.               outfile(),               /* outputs the checkbook data        */
  85.               pause(),                 /* Press <Space> to continue         */
  86.               repeat_entry(),          /* prompts and enters data           */
  87.               save(),                  /* saves the list to a file          */
  88.               set_cursor(),            /* sets the cursor position          */
  89.               shell_out();             /* shells out to DOS                 */
  90.   char        *Version = "CB 1.0 (C) Sep 1989 by Steven \"Noji\" Ratzlaff";
  91. #include "cbmain.inc"
  92. /*----------------------------------------------------------------------------
  93.  *  transact():  Transacts whatever business is needed by calling all other
  94.  *            routines pertinent to the requests.
  95.  *--------------------------------------------------------------------------*/
  96.   void
  97. transact(fname, yn)
  98.   char        *fname;                  /* filename of the account file      */
  99.   int         yn;                      /* create a new account?             */
  100. {
  101.   FILE        *fp;                     /* pointer to the account file       */
  102.   struct Record
  103.               *rec;                    /* pointer to a record               */
  104.   char        line[MAX_LINE];          /* input line from the file          */
  105.   int         sel = 0,                 /* transaction selection             */
  106.               data_entered = FALSE,    /* has data been entered?            */
  107.               save_executed = FALSE,   /* has the new data been saved?      */
  108.               i = 0;                   /* arbitrary counter                 */
  109.   double      total;                   /* total from adding machine         */
  110.   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  111.   if (yn != 'y')                       /* if no new file is to be created   */
  112.   {
  113.     fp = fopen(fname, "r");            /* open the file                     */
  114.     while (fgets(line, MAX_LINE, fp))  /* read the contents                 */
  115.     {
  116.       rec = (struct Record *) malloc((unsigned) sizeof(struct Record));
  117.       sscanf(line, "%[^:]:%[^:]:%[^:]:%[^:]:%[^:]:",
  118.              rec->check, rec->date, rec->amt, rec->pur, rec->bal);
  119.       rec->ind = ++index;
  120.       rec->next = NULL;
  121.       if (head == NULL)
  122.         head = rec;
  123.       else
  124.         cur->next = rec;
  125.       cur = tail = rec;
  126.       if (atoi(rec->check) > 100)      /* if we have a valid check number   */
  127.         strcpy(last_check, rec->check);
  128.     }
  129.     fclose(fp);                        /* close the file                    */
  130.   }                                    /* end of if (yn != 'y')             */
  131.                    /*------------------------------------*
  132.                     *          Main Menu Loop            *
  133.                     *------------------------------------*/
  134.   do {
  135.     clrscr();                          /* clear the screen                  */
  136.     sel = 0;
  137.     cur = tail;
  138.     printf("%40s\n\n", "Checkbook Main Menu");
  139.     printf("Select an action:  \n\n"
  140.            "  E>nter a transaction             L>ist the account\n"
  141.            "  D>irectory of accounts           M>ake a change\n"
  142.            "  A>dding machine                  I>nstructions\n"
  143.            "  B>alance the account             O>utput to a file\n"
  144.            "  C>ommand Shell                   R>estricted\n"
  145.            "  S>ave                            Q>uit\n");
  146.     gotoxy(20, 3);
  147.     while (sel!='e' && sel!='d' && sel!='l' && sel!='a' && sel!='m' &&
  148.            sel!='b' && sel!='o' && sel!='i' && sel!='s' && sel!='q' &&
  149.            sel!='c' && sel!=ESC)
  150.       sel = tolower(getch());
  151.     gotoxy(1, CURSOR);
  152.     switch (sel)
  153.     {
  154.       case  'e' :  enter_data();                           /* enter data    */
  155.                    data_entered = TRUE;
  156.                    save_executed = FALSE;
  157.                    break;
  158.       case  'd' :  directory(TRUE);                        /* directory     */
  159.                    break;
  160.       case  'l' :  list();                                 /* list the data */
  161.                    break;
  162.       case  'a' :  printf("Adding machine [enter alone to quit]:\n\n");
  163.                    repeat_entry(line, &total);
  164.                    printf("                   Total:  %9.2f\n", total);
  165.                    pause();
  166.                    break;
  167.       case  'm' :  make_change();                          /* make a change */
  168.                    data_entered = TRUE;
  169.                    save_executed = FALSE;
  170.                    break;
  171.       case  'c' :  shell_out();                            /* shell to DOS  */
  172.                    break;
  173.       case  'b' :  balance();                              /* balance acct  */
  174.                    break;
  175.       case  'o' :  outfile();                              /* output data   */
  176.                    break;
  177.       case  'i' :  instructions();                         /* instructions  */
  178.                    break;
  179.       case  's' :  save(fname);                            /* save entries  */
  180.                    save_executed = TRUE;
  181.                    break;
  182.       case  'q' :
  183.       case  ESC :  if (data_entered && !save_executed && cur != NULL)
  184.                    {
  185.                      printf("  Save changes and new entries?  ");
  186.                      while (i != 'y' && i != 'n')
  187.                        i = tolower(getch());
  188.                      if (i == 'y')
  189.                        save(fname);
  190.                    }
  191.       default   :  break;
  192.     }                                  /* end of switch (sel)               */
  193.   } while (sel != ESC && sel != 'q');  /* end of do { ...                   */
  194. }                                      /* end of transact()                 */
  195. /*----------------------------------------------------------------------------
  196.  *  balance():  Aids the user in balancing the checkbook account.
  197.  *--------------------------------------------------------------------------*/
  198.   void
  199. balance()
  200. {
  201.   char        endbal[INPUT_SP],        /* ending bank balance               */
  202.               odbal[INPUT_SP],         /* ending overdraft balance          */
  203.               c_checks[INPUT_SP],      /* outstanding checks                */
  204.               c_deps[INPUT_SP],        /*      "      deposits              */
  205.               c_ints[INPUT_SP],        /*      "      interests             */
  206.               c_charges[INPUT_SP],     /*      "      other charges         */
  207.               chk_num[INPUT_SP],       /* beginning check number            */
  208.               overunder[INPUT_SP];     /* over or under?                    */
  209.   int         yn = 0;                  /* input response                    */
  210.   double      end_bal,                 /* ending bank balance               */
  211.               od_bal,                  /* ending overdraft balance          */
  212.               checks,                  /* outstanding checks                */
  213.               deposits,                /*      "      deposits              */
  214.               ints,                    /*      "      interests             */
  215.               charges,                 /*      "      other charges         */
  216.               last,                    /* the amount of the last balance    */
  217.               total = 0.0,             /* total after all calculations      */
  218.               diff;                    /* difference between bank and user  */
  219.   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  220.   printf("  Balance the account? [ <Y>es  <N>o  <I>nstructions ]  ");
  221.   while (yn != 'y' && yn != 'n' && yn != 'i' && yn != ESC)
  222.     yn = tolower(getch());
  223.   if (yn == 'y' || yn == 'i')
  224.   {
  225.     if (yn == 'y')                     /* ready to balance the account      */
  226.     {
  227.       yn = 0;
  228.       gotoxy(1, wherey());
  229.       printf("  Total a continuous range of outstanding checks?          ");
  230.       gotoxy(52, wherey());
  231.       while (yn != 'y' && yn != 'n')
  232.         yn = tolower(getch());
  233.       gotoxy(1, wherey());
  234.       if (yn == 'y')
  235.       {
  236.         yn = 0;
  237.         printf("  Enter the starting check number:                         ");
  238.         gotoxy(37, wherey());
  239.         gets(chk_num);
  240.         for (cur = head; cur != NULL && strcmp(chk_num, cur->check);
  241.              cur = cur->next);
  242.         for (total = 0.0; cur != NULL; cur = cur->next)
  243.           if (atoi(cur->check) > 100)
  244.             total += atof(cur->amt);
  245.       }
  246.       printf("  Enter the ending bank statement balance:                 ");
  247.       gotoxy(45, wherey());
  248.       gets(endbal);
  249.       end_bal = atof(endbal);
  250.       printf("  Enter the ending overdraft or Visa debit balance:  ");
  251.       gets(odbal);
  252.       od_bal = atof(odbal);
  253.       printf("  Enter %s checks and Visa debits:\n\n",
  254.              (yn == 'y' ? "other outstanding" : "outstanding"));
  255.       repeat_entry(c_checks, &checks);
  256.       checks += total;
  257.       printf("  Enter outstanding deposits:\n\n");
  258.       repeat_entry(c_deps, &deposits);
  259.       printf("  Enter interests and dividends:\n\n");
  260.       repeat_entry(c_ints, &ints);
  261.       printf("  Enter other charges:\n\n");
  262.       repeat_entry(c_charges, &charges);
  263.       last = atof(tail->bal);
  264.       total = end_bal - od_bal - checks + deposits - ints + charges;
  265.       diff = fabs(total - last);       /* find the difference               */
  266.       if (diff <  0.001)               /*   C floating point oddity         */
  267.         printf("\n  %c%c%c  Good job...your account balanced.  %c%c%c\n\n",
  268.                2, 2, 2, 2, 2, 2);
  269.       else
  270.       {
  271.         if (last > total)              /* checkbook is over                 */
  272.           strcpy(overunder, "over");
  273.         else                           /* checkbook is under                */
  274.           strcpy(overunder, "under");
  275.         printf("\n  Your account is %s by %-8.2f\n\n", overunder, diff);
  276.         printf("%s%8.2f\n%s%8.2f\n\n",
  277.                "    Account balance:  ", last,
  278.                "    Bank balance:     ", total);
  279.       }
  280.     }                                  /* end of if (yn == 'y')             */
  281.     else                               /* need instructions                 */
  282.     {
  283.       clrscr();
  284.       printf("                  Instructions for Balancing your Account\n\n"
  285.              "Write down:\n"
  286.              "   1. The ending bank balance\n"
  287.              "   2. The ending overdraft or Visa debit total\n"
  288.              "   3. Outstanding checks and Visa debits\n"
  289.              "   4. Outstanding deposits\n"
  290.              "   5. The overdraft or Visa debit finance charges\n"
  291.              "   6. Excess draft and other charges\n"
  292.              "   7. Loan payments not yet entered\n"
  293.              "   8. Overdraft or Visa debit payments made by cash\n"
  294.              "   9. Interests and dividends\n\n"
  295.       "Enter interests, dividends, and overdraft cash payments under\n"
  296.       "   'Interests'.\n\n"
  297.       "Enter the overdraft finance charges, excess draft charges, unentered\n"
  298.       "   loan payments, and other charges under 'Other Charges'.\n\n");
  299.       printf("Enter the following formats into the account:\n"
  300.       "   The Visa cash payments as DEP      The loan payments as UCC\n"
  301.       "   The Visa finance charges as VIS    Interests and dividends as DEP\n"
  302.       "   The excess draft charge as XS      All other charges as OTH\n");
  303.     }                                  /* end of else of if (yn == 'y')     */
  304.   pause();
  305.   }                                    /* end of if (yn == 'y' || ...       */
  306. }                                      /* end of balance()                  */
  307. /*----------------------------------------------------------------------------
  308.  *  date_format():  Formats the string date to the standard format set by this
  309.  *            program.
  310.  *--------------------------------------------------------------------------*/
  311.   void
  312. date_format(dt)
  313.   char        *dt;                     /* input date string                 */
  314. {
  315.   char        c_day[INPUT_SP],         /* the day string                    */
  316.               c_month[INPUT_SP],       /* the month string                  */
  317.               c_year[INPUT_SP];        /* the year string                   */
  318.   int         len,                     /* length of the string              */
  319.               first = 0,               /* position of the first dash        */
  320.               sec = 0,                 /*     "     "  "  second  "         */
  321.               n_day,                   /* day number                        */
  322.               n_month,                 /* month number                      */
  323.               i;                       /* arbitrary counter                 */
  324.   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  325.   if (dt[0] == '\0')
  326.     get_todays_date(dt);
  327.   len = (int) strlen(dt);
  328.   if (len != 9)
  329.   {
  330.     for (i = 0; i < len && dt[first] != '-' && dt[first] != '/'; i++)
  331.       if (dt[i] == '-' || dt[i] == '/')               /* find the first '-' */
  332.         first = i;
  333.     for (i = 0; i < len; i++)
  334.       if (dt[i] == '-' || dt[i] == '/')               /* find the last '-'  */
  335.         sec = i;
  336.     strcpy(c_day, dt);
  337.     if (first == sec)                                 /* if only one '-'    */
  338.     {
  339.       get_todays_date(c_year);                        /* provide year       */
  340.       c_year[0] = c_year[7];
  341.       c_year[1] = c_year[8];
  342.       c_year[2] = '\0';
  343.       if (isdigit(dt[0]))                             /* get the month      */
  344.       {
  345.         dt[first] = '\0';
  346.         n_month = atoi(dt);
  347.       }
  348.       else
  349.       {
  350.         dt[3] = '\0';
  351.         strlwr(dt);
  352.         for (i = 1; i < 13; i++)
  353.           if (strcmp(dt, strlwr(month[i])) == 0)
  354.             n_month = i;
  355.       }                                /* end of if (isdigit(dt[0]))        */
  356.       strcpy(c_month, month[n_month]);
  357.       c_day[0] = c_day[first + 1];
  358.       c_day[1] = c_day[first + 2];
  359.       c_day[2] = '\0';
  360.     }                                  /* end of if (first == sec)          */
  361.     else
  362.       if (dt[first] == '-')
  363.         sscanf(dt, "%[^-]-%[^-]-%[^-]", c_day, c_month, c_year);
  364.       else
  365.         sscanf(dt, "%[^/]/%[^/]/%[^/]", c_day, c_month, c_year);
  366.     n_day = atoi(c_day);
  367.     if (n_day < DEC && c_day[0] != '0')          /* leading zeroes in day   */
  368.     {
  369.       c_day[1] = c_day[0];
  370.       c_day[0] = '0';
  371.       c_day[2] = '\0';
  372.     }
  373.     strcpy(dt, c_day);
  374.     strcat(dt, "-");
  375.     strcat(dt, c_month);
  376.     strcat(dt, "-");
  377.     strcat(dt, c_year);
  378.   }                                    /* end of if (len != 9)              */
  379.   strlwr(dt);
  380.   dt[3] -= 32;
  381. }                                      /* end of date_format()              */
  382. /*----------------------------------------------------------------------------
  383.  *  enter_data():  Prompts user for input and enters the data into a structure
  384.  *            pointed at by cur.
  385.  *--------------------------------------------------------------------------*/
  386.   void
  387. enter_data()
  388. {
  389.   struct Record
  390.               *rec;                    /* pointer to a record               */
  391.   int         ind,                     /* index into the array              */
  392.               xcur,                    /* current x position                */
  393.               ycur,                    /*    "    y    "                    */
  394.               c = 0;                   /* delimiter of the input string     */
  395.   char        todays_date[INPUT_SP];   /* a copy of today's date            */
  396.   double      temp;                    /* temporary floaing point storage   */
  397.   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  398.   printf("  Transaction Entry");
  399.   while (c != ESC)
  400.   {
  401.     rec = (struct Record *) malloc((unsigned) sizeof(struct Record));
  402.     *rec->check = *rec->date = *rec->amt = *rec->pur = *rec->bal = '\0';
  403.     get_todays_date(todays_date);
  404.     if (cur != NULL)
  405.     {
  406.       printf("  --  Last Entry:    \n\n%s%s\n\n",
  407.              "Ind  Item     Date      Amount  ",
  408.              "Purpose                                 Balance");
  409.       printf("%3d  %4s  %9s   %7s  %-38s %8s\n\n",
  410.              cur->ind, cur->check, cur->date, cur->amt, cur->pur, cur->bal);
  411.       strcpy(input[1].var, cur->date);
  412.     }
  413.     else
  414.     {
  415.       printf(":\n\n");
  416.       strcpy(input[1].var, todays_date);
  417.     }
  418.     input[0].var[0] = input[2].var[0] = input[3].var[0] = '\0';
  419.     for (ind = 0; ind < ELEMENTS && c != ESC; ind++)
  420.     {
  421.       printf("  %s  ", input[ind].msg);          /* print out the prompt    */
  422.       get_cursor(&xcur, &ycur);
  423.       if (ind == 0 && last_check[0])             /* find the next check #   */
  424.         itoa(atoi(last_check)+1, input[ind].var, 10);
  425.       if (ind == 0 || ind == 1)
  426.         printf(input[ind].var);
  427.       if (ind == 1)
  428.         do {
  429.           c = read_string(input[ind].var);
  430.           switch (c)
  431.           {
  432.             case  END   :  if (strcmp(input[ind].var, cur->date) == 0 ||
  433.                                cur == NULL)
  434.                              strcpy(input[ind].var, todays_date);
  435.                            else
  436.                              strcpy(input[ind].var, cur->date);
  437.                            break;
  438.             case  UP    :
  439.             case  DN    :
  440.             case  PGUP  :
  441.             case  PGDN  :  increment_date(input[ind].var, c);
  442.                            break;
  443.             default     :  break;
  444.           }                                      /* end of switch (c)       */
  445.           set_cursor(xcur, ycur);
  446.           printf(input[ind].var);
  447.         } while (c==END || c==UP || c==DN || c==PGUP || c==PGDN);
  448.       else
  449.         c = read_string(input[ind].var);         /* read in the string      */
  450.       set_cursor(xcur, ycur);
  451.       printf("%s\n", input[ind].var);            /* print the string out    */
  452.     }                                  /* end of for (ind = 0...            */
  453.     if (c != ESC)
  454.     {
  455.       strupr(input[0].var);
  456.       strcpy(rec->check, input[0].var);
  457.       strcpy(rec->date, input[1].var);
  458.       strcpy(rec->amt, input[2].var);
  459.       strcpy(rec->pur, input[3].var);
  460.       date_format(rec->date);
  461.       num_format(rec->amt);
  462.       printf("\n     %4s  %9s   %7s  %-38s\n\n",
  463.              rec->check, rec->date, rec->amt, rec->pur);
  464.       get_cursor(&xcur, &ycur);
  465.       printf("  Is this correct?  ");
  466.       while (c != 'y' && c != 'n')
  467.         c = tolower(getch());
  468.       set_cursor(xcur, ycur);
  469.       if (c == 'y')
  470.       {
  471.         rec->ind = ++index;
  472.         if (head == NULL)
  473.           if (stricmp(rec->check,"DEP") == 0)
  474.             temp = atof(beg_bal) + atof(rec->amt);
  475.           else
  476.             temp = atof(beg_bal) - atof(rec->amt);
  477.         else
  478.           if (stricmp(rec->check,"DEP") == 0)
  479.             temp = atof(cur->bal) + atof(rec->amt);
  480.           else
  481.             temp = atof(cur->bal) - atof(rec->amt);
  482.         gcvt(temp, 8, rec->bal);
  483.         num_format(rec->bal);
  484.         rec->next = NULL;
  485.         if (head == NULL)
  486.           head = rec;
  487.         else
  488.           cur->next = rec;
  489.         cur = tail = rec;
  490.         if (atoi(rec->check) > 100)    /* if we have a valid check number   */
  491.           strcpy(last_check, rec->check);
  492.       }                                /* end of if (c == 'y')              */
  493.     }                                  /* end of if (c != ESC)              */
  494.   }                                    /* end of while (c != ESC)           */
  495. }                                      /* end of enter_data()               */
  496. /*----------------------------------------------------------------------------
  497.  *  list():  Displays the contents of the list.
  498.  *--------------------------------------------------------------------------*/
  499.   void
  500. list()
  501. {
  502.   int         c = 0,                   /* primary selection                 */
  503.               d = 0,                   /* secondary selection               */
  504.               ind,                     /* index into the array              */
  505.               proceed = TRUE,          /* the scrolling may proceed         */
  506.               lines = 0;               /* lines appearing on the screen     */
  507.   double      total = 0.0;             /* total of listed amounts           */
  508.   char        ch[INPUT_SP],            /* buffer for the check number       */
  509.               dt[INPUT_SP],            /*    "    "   "  date               */
  510.               am[INPUT_SP],            /*    "    "   "  amount             */
  511.               pu[MSG_LEN];             /*    "    "   "  purpose            */
  512.   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  513.   printf("  Listing by\n\n%s",
  514.          "    A>ll transactions\n"
  515.          "    S>pecific items\n"
  516.          "    D>ate beginning\n");
  517.   gotoxy(15, CURSOR);
  518.   while (c != 'a' && c != 's' && c != 'd' && c != ESC)
  519.     c = tolower(getch());
  520.   if (c != ESC)
  521.   {
  522.     gotoxy(1, CURSOR + 6);
  523.     cur = head;
  524.     if (c == 's')
  525.     {
  526.       printf("    Enter the items to list:\n\n%s",
  527.              "      Check / Item:\n"
  528.              "      Date:\n"
  529.              "      Amount:\n"
  530.              "      Purpose:\n");
  531.       do {                                       /* all can't be empty      */
  532.         for (ind = 0; ind < ELEMENTS; ind++)
  533.         {
  534.           gotoxy(23, CURSOR + ind + 8);
  535.           input[ind].var[0] = '\0';
  536.           gets(input[ind].var);
  537.           strlwr(input[ind].var);
  538.         }
  539.       } while (!input[0].var[0] && !input[1].var[0] &&
  540.              !input[2].var[0] && !input[3].var[0]);
  541.     }                                  /* end of if (c == 's')              */
  542.     else
  543.       if (c == 'd')
  544.       {
  545.         printf("    Enter the starting date:  ");
  546.         gets(input[1].var);
  547.         date_format(input[1].var);
  548.         strcpy(dt, cur->date);
  549.         while (cur != NULL && before_date(dt, input[1].var))
  550.         {
  551.           cur = cur->next;
  552.           strcpy(dt, cur->date);
  553.         }
  554.       }                                /* end of if (c == 'd')              */
  555.     printf("\n%s%s\n\n",
  556.            "Ind  Item     Date      Amount  ",
  557.            "Purpose                                 Balance");
  558.     while (cur != NULL && d != ESC && d != 'q')
  559.     {
  560.       switch (c)
  561.       {
  562.         case  'a'  :
  563.         case  'd'  : printf("%3d  %4s  %9s   %7s  %-38s %8s\n",
  564.                             cur->ind, cur->check, cur->date,
  565.                             cur->amt, cur->pur, cur->bal);
  566.                      lines++;
  567.                      break;
  568.         case  's'  : strcpy(ch, cur->check);
  569.                      strlwr(ch);
  570.                      strcpy(dt, cur->date);
  571.                      strlwr(dt);
  572.                      strcpy(am, cur->amt);
  573.                      strlwr(am);
  574.                      strcpy(pu, cur->pur);
  575.                      strlwr(pu);
  576.                      if (strstr(ch, input[0].var) && strstr(dt, input[1].var) &&
  577.                          strstr(am, input[2].var) && strstr(pu, input[3].var))
  578.                      {
  579.                        printf("%3d  %4s  %9s   %7s  %-38s %8s\n",
  580.                          cur->ind, cur->check, cur->date,
  581.                          cur->amt, cur->pur, cur->bal);
  582.                        lines++;
  583.                        proceed = TRUE;
  584.                        total += atof(cur->amt);
  585.                      }
  586.                      else
  587.                        proceed = FALSE;
  588.         default    : break;
  589.       }                                /* end of switch (c)                 */
  590.       if ((lines >= 22 || d == '\r') && proceed)
  591.       {
  592.         lines = 0;
  593.         printf("--- <Space> = Continue | <Enter> = Step | <Esc> = Quit ---");
  594.         d = tolower(getch());
  595.         gotoxy(1, wherey());
  596.         printf("                                                           ");
  597.         gotoxy(1, wherey());
  598.         if (d == SP)
  599.           printf("\n%s%s\n\n",
  600.                  "Ind  Item     Date      Amount  ",
  601.                  "Purpose                                 Balance");
  602.       }
  603.       cur = cur->next;
  604.     }                                  /* end of while (cur != NULL ...)    */
  605.     if (c == 's')
  606.       printf("\n                     %9.2f  Total\n", total);
  607.     pause();
  608.   }                                    /* end of if (c != ESC)              */
  609. }                                      /* end of list()                     */
  610. /*----------------------------------------------------------------------------
  611.  *  make_change():  Prompts the user for changes to be made on the list data
  612.  *            and incorporates those changes.
  613.  *--------------------------------------------------------------------------*/
  614.   void
  615. make_change()
  616. {
  617.   char        c_ind[INPUT_SP],         /* input index number to search for  */
  618.               old_item[INPUT_SP],      /* old item string                   */
  619.               old_amt[INPUT_SP];       /* old amount string                 */
  620.   double      temp1, temp2;            /* temporary double values           */
  621.   int         item_changed = FALSE,    /* the item was changed              */
  622.               amt_changed = FALSE,     /* the amount changed                */
  623.               xcur,                    /* current x position                */
  624.               ycur,                    /*    "    y    "                    */
  625.               c = 0,                   /* returned input value              */
  626.               ind = 0,                 /* index counter                     */
  627.               rv = 0;                  /* return value from function        */
  628.   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  629.   c_ind[0] = '\0';
  630.   printf("  Enter index number of item to change [<Esc> to abort]:  ");
  631.   rv = read_string(c_ind);
  632.   printf("%s\n\n", c_ind);
  633.   if (rv != ESC && rv != UP && rv != DN && rv != PGUP && rv != PGDN)
  634.   {
  635.     rv = atoi(c_ind);
  636.     for (cur = head; cur != NULL && cur->ind != rv; cur = cur->next)
  637.       ;
  638.     if (cur != NULL)
  639.     {
  640.       gotoxy(1, CURSOR);
  641.       printf("%s%s\n\n",
  642.              "Ind  Item     Date      Amount  ",
  643.              "Purpose                                 Balance");
  644.       printf("%3d  %4s  %9s   %7s  %-38s %8s\n\n",
  645.              cur->ind, cur->check, cur->date, cur->amt, cur->pur, cur->bal);
  646.       printf("  Change this record?  ");
  647.       while (c != 'y' && c != 'n')
  648.         c = tolower(getch());
  649.       if (c == 'y')
  650.       {
  651.         c = 0;
  652.         strcpy(old_item, cur->check);
  653.         strcpy(old_amt, cur->amt);
  654.         strcpy(input[0].var, cur->check);
  655.         strcpy(input[1].var, cur->date);
  656.         strcpy(input[2].var, cur->amt);
  657.         strcpy(input[3].var, cur->pur);
  658.         gotoxy(1, CURSOR + 4);
  659.         printf("  Enter the changes:   \n\n");
  660.         for (ind = 0; ind < ELEMENTS && rv != ESC; ind++)
  661.         {
  662.           printf("  %s  ", input[ind].msg);      /* print out the prompt    */
  663.           get_cursor(&xcur, &ycur);
  664.           printf(input[ind].var);
  665.           if (ind == 1)
  666.             do {
  667.               rv = read_string(input[ind].var);
  668.               if (rv == UP || rv == DN || rv == PGUP || rv == PGDN)
  669.                 increment_date(input[ind].var, rv);
  670.               set_cursor(xcur, ycur);
  671.               printf(input[ind].var);
  672.             } while (rv==UP || rv==DN || rv==PGUP || rv==PGDN);
  673.           else
  674.             rv = read_string(input[ind].var);    /* read in the string      */
  675.           set_cursor(xcur, ycur);
  676.           printf("%s\n", input[ind].var);        /* print the string out    */
  677.         }                              /* end of for (ind = 0...            */
  678.         if (rv != ESC)
  679.         {
  680.           strupr(input[0].var);
  681.           date_format(input[1].var);
  682.           num_format(input[2].var);
  683.           printf("\n     %4s  %9s   %7s  %-38s\n\n",
  684.                  input[0].var, input[1].var, input[2].var, input[3].var);
  685.           printf("  Is this correct?  ");
  686.           while (c != 'y' && c != 'n')
  687.             c = tolower(getch());
  688.           if (c == 'y')
  689.           {
  690.             item_changed = strcmp(input[0].var, cur->check);
  691.             amt_changed = strcmp(input[2].var, cur->amt);
  692.             strcpy(cur->check, input[0].var);
  693.             strcpy(cur->date, input[1].var);
  694.             strcpy(cur->amt, input[2].var);
  695.             strcpy(cur->pur, input[3].var);
  696.             if (item_changed)
  697.             {
  698.               if ((stricmp(old_item, "DEP") == 0 &&
  699.                    stricmp(input[0].var, "DEP") != 0) ||
  700.                   (stricmp(old_item, "DEP") != 0 &&
  701.                    stricmp(input[0].var, "DEP") == 0))
  702.               {
  703.                 temp1 = atof(input[2].var) + atof(old_amt);
  704.                 while (cur != NULL)
  705.                 {
  706.                   if (stricmp(old_item, "DEP") == 0 &&
  707.                       stricmp(input[0].var, "DEP") != 0)
  708.                     temp2 = atof(cur->bal) - temp1;
  709.                   else
  710.                     temp2 = atof(cur->bal) + temp1;
  711.                   gcvt(temp2, 8, cur->bal);
  712.                   num_format(cur->bal);
  713.                   cur = cur->next;
  714.                 }                      /* end of while (cur != NULL)        */
  715.               }                        /* end of if (stricmp(...))          */
  716.             }                          /* end of if (item_changed)          */
  717.             else
  718.               if (amt_changed)
  719.               {
  720.                 if (stricmp(old_item, "DEP") == 0)
  721.                   temp1 = atof(input[2].var) - atof(old_amt);
  722.                 else
  723.                   temp1 = atof(old_amt) - atof(input[2].var);
  724.                 while (cur != NULL)
  725.                 {
  726.                   temp2 = atof(cur->bal) + temp1;
  727.                   gcvt(temp2, 8, cur->bal);
  728.                   num_format(cur->bal);
  729.                   cur = cur->next;
  730.                 }
  731.               }                        /* end of if (amt_changed)           */
  732.           }                            /* end of if (c == 'y')              */
  733.         }                              /* end of if (rv != ESC)             */
  734.       }                                /* end of if (c == 'y')              */
  735.     }                                  /* end of if (cur != NULL)           */
  736.     else
  737.     {
  738.       printf("  Index number %d does not exist\n", rv);
  739.       pause();
  740.     }                                  /* end of else of if (cur != NULL)   */
  741.   }                                    /* end of if (rv != ESC ...)         */
  742. }                                      /* end of make_change()              */
  743. /*----------------------------------------------------------------------------
  744.  *  outfile():  Outputs the list data to a file.
  745.  *--------------------------------------------------------------------------*/
  746.   void
  747. outfile()
  748. {
  749.   FILE        *fp;                     /* pointer to the output file        */
  750.   char        fname[MSG_LEN];          /* name of file to write to          */
  751.   int         rv = 0;                  /* return value from function        */
  752.   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  753.   fname[0] = '\0';
  754.   printf("  Enter the filename to store the account [<Esc> to abort]:  ");
  755.   rv = read_string(fname);
  756.   printf("%s\n\n", fname);
  757.   if (rv != ESC && rv != UP && rv != DN && rv != PGUP && rv != PGDN)
  758.   {
  759.     if (fp = fopen(fname, "w"))
  760.     {
  761.       fprintf(fp, "%s%s\n\n",
  762.              "Ind  Item     Date      Amount  ",
  763.              "Purpose                                 Balance");
  764.       for (cur = head; cur != NULL; cur = cur->next)
  765.         fprintf(fp, "%3d  %4s  %9s   %7s  %-38s %8s\n",
  766.                cur->ind, cur->check, cur->date, cur->amt,
  767.                cur->pur, cur->bal);
  768.       fclose(fp);
  769.     }                                  /* end of if (fp = fopen(fname...))  */
  770.     else
  771.     {
  772.       printf("  *** File '%s' could not be written to\n", fname);
  773.       pause();
  774.     }
  775.   }                                    /* end of if (rv != ESC ...)         */
  776. }                                      /* end of outfile()                  */
  777. /*----------------------------------------------------------------------------
  778.  *  End of CB.C
  779.  *--------------------------------------------------------------------------*/
  780.