Professional Documents
Culture Documents
PROGRAMMING
ASSIGNMENT No 2
By David Koncewicz
HCCA4203
CONTENTS
INTRODUCTION
This report gives a brief description on the construction of the program ‘Wibbly Wobbly
Stock System’ that I have w ritten using the ‘C’ language. The program allow s a user to input
data or load data from a file called ‘Toydata.dta’. A user can then add a new product, add a
stock item, remove a stock item or delete a w hole record containing the toy product details.
Tw o linked list are used, one for the toydata, and one for the transactions i.e. adding a stock
item etc...
The program w as w ritten using the Borland v2 IDE C++ compiler, on a 486 processor, 12mb
machine. See appendix for the code listing.
SUMMARY
The program could have been w ritten using a tree structure as opposed to the linked list that I
used, as this seems to be a better method of storing, ordering and retrieving data, how ever,
as this is a small project in comparison, the list seems to w ork quite w ell.
I could have w ritten the program to make the functions more general, but time constraints and
lack of know ledge at the time prevented this.
Programming assignment 2 - HCCA4203 Page 2.
The program is quite self explanatory, and should be quite easy to navigate. When view ing
the inventory on screen, any products that need reordering are show n in red text. There are
pop-up menus to display messages, to help if any errors occur. See Fig 1 for database
w indow .
Status line/prompts
PSEUDO CODE
Loading the file
if no existing nodes
If memory available
create first node and use as a dummy first node
make pointer to last = null
make pointer to next = null
If memory available
create another node
(insert sort)
while node product code < next node product code and node not reached end
node = node next
If no existing node
If memory available
create first node
make pointer to next = null
else
If memory available
create another node
1.RECORD.H
2.WIBMAIN.CPP
3.WIBMENU.CPP
4.FILEHAND.CPP
5.NODES.CPP
6.NEWPROD.CPP
7.EDITREC.CPP
8.PRINTINV.CPP
These file are grouped w ithin the project file name WIB001.PRJ, and are described as
follow s:
RECORD.H contains all the function prototypes, constants, enums and global variables
declarations (see RECORD.H for description and use of variables).
WIBMAIN.CPP contains the user selection routines for adding, removing, saving files etc.
The global variables are also defined here. These global variables are used as temporary
storage betw een file reading and user input before assigning the data to a node.
WIBMENU.CPP contains most of the screen user options, pop-up box, header and footer
text. I found by doing this, made it easier to co-ordinate the w indow positions, colours and
text. Functions in the other files also contain text, but most of this text is passed to
functions w ithin this file that do the alignment such as the header and footer text. I
created a function called CtrTxt, that centres the text in relation to the main assigned
screen area.
FILEHAND.CPP as you might have guessed, contains all the functions for loading and
saving the toydata, transaction and re-order files. The files, w hen printed, show the
appropriate headings and footers etc...
NODES.CPP contains the functions involved in creating, adding and deleting the nodes. It
also has tw o functions for adding the data to the toy and transaction nodes.
NEWPROD allow s the user to create a new product. After all the details such as the
product cod, description etc... have been entered, the user has a choice to save the
record or exit the function. The product code can be a combination of numbers or letters,
and w hen entered, are converted to capitals w here appropriate. If the code is less than
six digits, the remainder is filled w ith appending 0s, not necessary, but makes it look a bit
tidier w hen view ing the records. The stock digits have been restricted ( see RECORD.H
constants), this w as mainly for cosmetic purposes, but also to help prevent an overflow
situation should a user fall a sleep w ith their finger on the numeric key w hile inputting!!!.
Programming assignment 2 - HCCA4203 Page 6.
EDITREC.CPP contains the functions used to enable the user to add, remove stock and
delete a record. The inputs the product code (which can be a combination of letters or
numbers) and match it w ith the corresponding ‘code in the node ‘, this is then passed to
the required function determined by an enum ID (see code RECORD.H) passed by the
variable ‘flag’ form the selected option w ithin WIBMAIN.CPP. Warning messages are give if
a user tries to remove more than in stock. It also w arns is a re-order is required
PRINTINV.CPP contains functions for printing the data on screen. It prints a max of n
lines at a time. When max n lines (full page) has been reached, the screen is halted,
giving the user a chance to exit or continue. This also occurs if the end of the linked list is
reached (otherwise viewing a page < max n would not be possible). When the list
reaches the end the pointer to the list is re-initialised to list start again, thus allow ing a
continuous loop of the data.
TESTING / PROBLEMS
I had to include an if statement in the save toydata function that prints the \n character, this
w as because I found that the extra line that w as created by placing in w ithin the same fprintf
function that prints the actual data, caused the last record to be duplicated w hen re-loading.
I also had to place the routine of creating the head node, w ithin the function that inserts each
node.
This w as because on terminating the program, a ‘null pointer assignment’ message w as
being generated w hich did not seem ‘safe’. The reason w hy I mention this is because by
placing the head node identifier w ithin this function, makes it less general, but as most of the
functions how ever, are specific to this program anyw ay, It does not make much difference.
Testing w as done mainly by inputting data and view ing it using the IDEs w atch and debug
facilities.
Letters w ere input w here numbers expected to test bad input w as not being passed to the
nodes.
When adding to a stock value, I found a negative number w as resulting due to the int signed
value being change by overflow . This prompted me to change from int to long int. Although I
restricted the number of digits that can be input, adding stock items could still have produce
this error.
Programming assignment 2 - HCCA4203 Page 7.
1000001 1 1 1.00
120345Meccano Master Set 10 2 49.99
120346Scalectric Racers 10 2 69.99
120350P ower Rangers Set 10 5 29.99
120355Junior Monopoly 12 5 12.99
120360Junior Master Chef 10 3 17.99
120365Hornby Train Set 12 5 64.99
120368Chemistry Set 5 2 24.99
120370Cry Baby Doll 10 5 19.99
120380Action Man Set 5 5 16.99
120385Lego Set 10 5 24.99
120386Dumper Truck 5 2 19.99
120387Junior Artist Set 5 2 34.99
120390Mini Cricket Set 8 2 26.99
120400Steve Davis Snooker 7 2 44.99
120410Sooty and Sweep 10 2 12.99
120411Barbie Doll Set 8 5 17.99
120412Junior Drum Kit 5 2 39.99
120420Warrior Battle Set 10 2 12.99
120440P aint by Numbers 6 2 12.99
120445Mini Keyboard 8 2 24.99
120446Junior Golf Set 6 2 69.99
120460Cowboy Suit 1 2 0.00
Transaction File
Total transactions = 1
Reorder List
Code Description Stock O/L P rice
100000 1 1 1 2 1.00
120380 Action Man Set 5 5 16.99
120460 Cowboy Suit 1 2 0.00
Programming assignment 2 - HCCA4203 Page 8.
CONCLUSION
The program could best be implemented using a tree structure, but to lack of time, prevented
this as I w as not sure as to how to go about this at the time, how ever, as this is a small
project in comparison, the list seems quite sufficient.
The programs functions could also have be made more ‘general’, but again, due to time
constraints and lack of know ledge at the time, I found I w as unable to achieve this for most of
the functions. The use of more type casting etc. w ould have aided this.
BIBLIOGRAPHY
Comprehensive C - By David Spuler
APPENDIX
The follow ing pages contain the code listing.
RECORD.H
//--------------------------------------------------------------------------
---
// The #defines
// Used for code and description I/P - see filename NEWPROD.CPP &
EDITREC.CPP
#define APENDZEROS(co) (strncat(co, "000000", ( (CODSIZE) -strlen(co))))
#define CAPSTR(s) {for (int i = 0; s[i] != NULL ; i++) s[i] =
toupper(s[i]);}
//--------------------------------------------------------------------------
---
// The enums.
/* Used for adding stock, removing stock, new product & delete product
-directs
func edit_reccord (see EDITREC.CPP) to appropriate func, also used for a
transaction type */
typedef enum { NEWPROD, ADDSTOK, REMSTOK, DELPROD } flag;
//--------------------------------------------------------------------------
---
// The structures.
Page 1/3
RECORD.H
}*rec_type;
}*tr_type;
//--------------------------------------------------------------------------
---
// The function prototypes.
Page 2/3
RECORD.H
// Defined in NEWPROD.CPP
void add_new_prod( void ); // User add a new product
// Defined in EDITREC.CPP
void edit_record(flag mode); // User add/remove stock etc..
//--------------------------------------------------------------------------
---
// The global variables - defined in WIBMAIN.CPP.
/* Assigned to, before passing on to node, when for example, reading in from
file - used in files FILEHAND.CPP, NODES.CPP & NEWPROD.CPP */
extern char Buff[]; // Temp buffer for cgets I/P
extern char Opt; // Hold user I/P option
extern char Cod[]; // Product code
extern char Des[]; // Description
extern long Stk; // Stock
extern long Lev; // Re-order level
extern float Pri; // Price
// end file
Page 3/3
WIBMAIN.CPP
/***************************************************************************
***
Program Wibly Wobbly Stock Control system.
gives a user the following choices (see also filename WIBMENU.CPP):
This file contains the main menu options and sub options
/***************************************************************************
*/
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include <dos.h> // For delay
#include "record.h"
//--------------------------------------------------------------------------
---
/* Global - used for assignment before passing on to struct vars.
for example reading in and writing to the files */
//--------------------------------------------------------------------------
---
// Pointers to head nodes for transactions and toydata lists
Page 1/4
WIBMAIN.CPP
//--------------------------------------------------------------------------
---
Page 2/4
WIBMAIN.CPP
};
switch(toupper((Opt = getch()))){
void sub_choice_save_fil(){
/***************************************************************************
***
Options to save a file type. See filename FILEHAND.CPP
****************************************************************************
**/
switch(toupper((Opt = getch()))){
Page 3/4
WIBMAIN.CPP
/***************************************************************************
***
Options view a list type - See filename PRINTSCR.CPP
****************************************************************************
**/
switch(toupper((Opt = getch()))){
Page 4/4
WIBMENU.CPP
Wibbly Wobbly
Page 1/1
FILEHAND.CPP
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include "record.h"
while( !feof(stream) ){
Page 1/4
FILEHAND.CPP
clearerr(stream);
}
fclose(stream); delay(1500);
}
else
MsgBox("Error: File/Data already loaded!");delay(1500);
};
DESSIZE, ptr->desc,
ptr->stock,
ptr->level,
ptr->price);
ptr = ptr->next;
};
Page 2/4
FILEHAND.CPP
DESSIZE, ptr->desc,
STKDIGIT, ptr->stock,
STKDIGIT, ptr->level,
ptr->price);
}
ptr = ptr->next;
}
fclose(stream);
};
if (FirstTR != NULL){
Page 3/4
FILEHAND.CPP
fputs(ptr->prodcod, stream);
switch(ptr->trtype){
ptr->time);
ptr = ptr->next; tcount++;
}
Page 4/4
NODES.CPP
#include <stdlib.h>
#include <string.h>
#include <time.h> // For transaction time
#include "record.h"
void * memoptr;
// Test for available memory
if(! (memoptr = malloc(size)) ){
MsgBox(strerror(errno));
exit (-1);
}
return memoptr;
};
rec_type newptr;
Page 1/3
NODES.CPP
return (newptr);
};
free(curptr);
tr_type newptr;
static tr_type curptr; // Current pointer position save on exit
Page 2/3
NODES.CPP
};
rec_type ass_rec_dat
(rec_type ptr, char *co, char *de, long st, long lv,
float pr){
/***************************************************************************
***
Assign the I/P toy data to the new node.
****************************************************************************
**/
strcpy(ptr->code, co);
strcpy(ptr->desc, de);
ptr->stock = st;
ptr->level = lv;
ptr->price= pr;
return ptr;
};
ptr->trtype = tr;
strcpy(ptr->prodcod, co);
ptr->units = unit;
strncpy(ptr->time, ctime(&t),16);
};
// end file
Page 3/3
NEWPROD.CPP
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include <dos.h>
#include "record.h"
for(;;){
Page 1/3
NEWPROD.CPP
// see RECORD.H
defines */
cputs("\r\n\n");
Buff[0] = STKDIGIT+1;
// Convert to long and
assign
if (sscanf(cgets(Buff),"%ld", &Stk) >= 1){
cputs("\r\n\n");
Buff[0] = STKDIGIT+1;
// Convert to long and
assign
if (sscanf(cgets(Buff),"%ld", &Lev) >= 1){
cputs("\r\n\n");
Buff[0] = PRIDIGIT+1;
// Convert to float and
assign
if (sscanf(cgets(Buff),"%f", &Pri) >= 1){
_setcursortype(_NOCURSOR);
FootTxt("");
HeadTxt("[RTN]=next [ANY]=redo [ESC]=exit");
Opt = getche();
// save if user requires
if (Opt == 27 || Opt == 13){
HeadTxt("Save this record [ESC]=cancel?");
// Create node & insert
(code order)
if ((getch()) != 27){
insert_sort();
break;
}
else
break; // Just break
}
}else break;
}else break;
Page 2/3
NEWPROD.CPP
void insert_sort(void){
/***************************************************************************
***
Inserts a node in ascending code order. loops through list break when next
highest number found or last node reached. Node is inserted between
highest
and lowest (obviously) - see NODES.CPP mak_rec_nod(). The data is passed
via parameters using global vars Cod, Desc, Stk, Lev & Pri for I/P
****************************************************************************
**/
ptr = ptr->next;
}
Page 3/3
EDITREC.CPP
for(;;){
fflush(stdin);
Buff[0] = CODSIZE+1;
Page 1/4
EDITREC.CPP
ItemScr();prt_result(ptr);
_setcursortype(_SOLIDCURSOR);
}
else{ MsgBox("No matching code");delay(500);
prt_prod_scr(); HeadTxt("Please enter the product
code");
}
}else break;
Page 2/4
EDITREC.CPP
HeadTxt("ADD UNITS");
FootTxt("Specify unit amount to add:");
Buff[0] = STKDIGIT+1;
HeadTxt("REMOVE UNITS");
FootTxt("Specify unit amount to remove:");
Buff[0] = STKDIGIT+1;
}
else{
MsgBox("Cannot remove more stock than exist!");delay(1500);
}
}
};
Page 3/4
EDITREC.CPP
_setcursortype(_NOCURSOR); ItemScr();
cprintf("%-*s\r\n\n%-*s\r\n\n%-*ld\r\n\n%-*ld\r\n\n%-*.2f",
CODSIZE, p->code,
DESSIZE, p->desc,
STKDIGIT, p->stock,
STKDIGIT, p->level,
PRIDIGIT, p->price);
};
// end file
Page 4/4
PRINTSCR.CPP
#include <conio.h>
#include <string.h>
#include "record.h"
/***************************************************************************
***
Prints the stock list on screen, MAXLINES at a time. Displayed with
heading
all within main boarder see WIBMENU.CPP
Page 1/4
PRINTSCR.CPP
}
else{
if(ptr->stock <= ptr->level) // Shows reorder level in red
textcolor(LIGHTRED); // Else in white
else
textcolor(WHITE);
DESSIZE, ptr->desc,
STKDIGIT, ptr->stock,
STKDIGIT, ptr->level,
PRIDIGIT, ptr->price);
ptr = ptr->next; lines++;
}
}
};
lines = 1;
clrscr();
if (ptr == NULL)
ptr = FirstTR;
Page 2/4
PRINTSCR.CPP
}
else
break;
}
else{
cprintf(" %-*s", CODSIZE, ptr->prodcod);
switch(ptr->trtype){
void prt_stats_scr(){
/***************************************************************************
***
Prints on screen statistic info, the total records in memory, amount of
re-orders required to bring one above re-order levels, total transactions
and total inventory value.
****************************************************************************
**/
// Count re-orders
required
if (rptr->stock <= rptr->level){
Page 3/4
PRINTSCR.CPP
Page 4/4