Link to home
Start Free TrialLog in
Avatar of Knoxy
Knoxy

asked on

Help with Hash Table creation??

Hi I was wondering if one of you guys
could help me as I'm at college doing a software
development course and are struggling with the code to
create a hash table. Could someone view my coding to
find out where I maybe going wrong.

The Hash Table has to be designed to read/write data from a Stock.txt file as well as updating, deleting, retrieving etc..

When compiling I get no errors and 17 warnings then when I try to run I get a "General protection exception" error. I think it maybe something to do with a pointer!

I'm using Borland 4.52 with Win XP pRO.

#include <iostream.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <iomanip.h>


//*** Named constants ***
const int SIZE = 101;
const int EMPTY = -1;
const int DELETED = -1;
const int NOTFOUND = -1;

//*** Stock record structure declaration ***
struct StockDetails
{
  long stocknum;
  char description[30];
  float price;
  int quantity;
};
struct StockTable
{
  StockDetails list [SIZE];
  int count;
};

//***********************************
//*** Table Operations Prototypes ***
//***********************************

//***Main operations ***
void CreateTable(StockTable&);
int Add(StockDetails, StockTable&);
void DisplayTable(const StockTable&);
int Delete(int, StockTable&);
int IsFull(const StockTable&);
//***Auxiliary Operations ***
int IsAt(int, const StockTable&);
int Retrieve(int, const StockTable&, StockDetails&);
int Update(const StockDetails&, StockTable&);
void Terminate(StockTable&);
int GetStockDetails(StockDetails&, StockTable&);
void DisplayRecord(int, StockTable&);
inline int Hash(int key)
{
      return key%SIZE;
}

//*** Other Function prototypes for hash table ***
int DisplayMenu(char*);
int GetOption(int);
void ExecuteOption(int, StockTable&);
void OpenFile(StockTable&);
void Print(StockTable&);
//***************************************
//*** End of function type prototypes ***
//***************************************

//** MAIN PROGRAM ***
void main()
{
      StockTable t;
      int opt, max;

      //*** Create empty table ***
      CreateTable(t);
      OpenFile(t);
      do
      {
            //*** Display Menu ***
            clrscr();
            max = DisplayMenu("1 - Create table\n2 - Add new inventory \n""3 - Remove inventory\n4 Display inventory\n5 Update inventory\n6 Retrieve inventory\n"
                                                "7 - Quit program\n");

            //*** Get user option ***
            opt = GetOption(max);
            //*** Execute users option ***
            ExecuteOption(opt,t);
      }
      while(opt!=max);
      getch();
}

//**************************************
//*** Auxiliary function definitions ***
//**************************************

//*** Create empty table ***
void CreateTable(StockTable& t)
{
      //*** Set count to zero ***
      t.count = 0;
      //*** Set all key fields to EMPTY ***
      for(int c=0; c<SIZE; c++)
            t.list[c].stocknum = EMPTY;
}

//*** Determine if Table is full ***
int IsFull(const StockTable& t)
{
      if(t.count==SIZE)
            return 1;
      else
            return 0;
}

//*** Find position of record in table ***
int IsAt(int key, const StockTable& t)
{
      int post = Hash(key);
      int start = post;

      //*** IF position not found ***
      while(t.list[post].stocknum!=key && t.list[post].stocknum!=EMPTY)
      {
            post=(post+1)%SIZE;
            if(post==start)
                  break;
      }
      //*** IF position not found ***
      if(t.list[post].stocknum!=key)
            return NOTFOUND;
      //*** IF position found ***
      else
            return post;
}

//*** Add new record ***
int Add(StockDetails sd, StockTable& t)
{
      //*** If Stock number exists or table full return ***
      if(IsAt(sd.stocknum,t)!=NOTFOUND ||IsFull(t))
            return 0;
      //*** Find insert position ***
      int post = Hash(sd.stocknum);
      while(t.list[post].stocknum!=EMPTY && t.list[post].stocknum!=DELETED)
            post=(post+1)%SIZE;
      //*** Add new entry ***
      t.list[post] = sd;
      t.count++;
      return 1;
}

//*** Delete record from table ***
int Delete(int key, StockTable& t)
{
      //*** Find entry to be deleted ***
      int post = IsAt(key,t);
      //*** If not found return ***
      if(post==NOTFOUND)
            return 0;
      DisplayRecord(key,t);
      //*** Delete by setting key field ***
      t.list[post].stocknum=EMPTY;
      t.count--;
      return 1;
}

//*** Displays a specified entry in table ***
int Retrieve(int key, const StockTable& t, StockDetails& sd)
{
      //*** Initialize empty record for fail ***
      StockDetails failed = {0,"",0.0,0};
      int post;
      //*** Find position ***
      if((post=IsAt(key,t))!= -1)
      {
            sd = t.list[post];
            return 1;
      }
      else
      {
            //*** Record is empty ***
            sd = failed;
            return 0;
      }
}

//*** Update specified record ***
int Update(const StockDetails& sd, StockTable& t)
{
      int post;

      //*** IF position not found ***
      if((post=IsAt(sd.stocknum,t))==-1)
            return 0;
      else
      {
            //*** Else update Record ***
            t.list[post] = sd;
            return 1;
      }
}

//*** Display contents of table ***
void DisplayTable(const StockTable& t)
{
      //*** Display headings ***
      cout<<"Catalogue number"<<setw(25)<<"Description"
             <<setw(12)<<"Price"<<setw(20)<<"quantity\n\n";
      //*** FOR size of table DO
      for(int c=0; c<SIZE; c++)
      {
            //*** Display valid records ***
            if(t.list[c].stocknum!=EMPTY && t.list[c].stocknum!=DELETED)
            {
                  cout<<t.list[c].stocknum
                  <<t.list[c].description
                          <<t.list[c].price
                          <<t.list[c].quantity<<endl;
            }
      }
}

//*** Terminate program ***
void Terminate(StockTable& t)
{
char option;
int count=t.count;
FILE *stockfile;
char str_stocknum[9];
char str_price[5];
char str_quantity[4];
char spacer[] = "\t\t\t";
cout<<"Do you wish to save changes before exiting  [Yes or No?] : ";
      cin>>option;
      if(option=='Y' || option=='y')
      {
            stockfile = fopen("C:\\Stock.txt","w");

            //*** FOR size of table DO ***
            for(int c=0; c<SIZE; c++)
            {
                  if(t.list[c].stocknum!=EMPTY && t.list[c].stocknum!=DELETED)
                  {
                  //*** convert members to string ***
                  ltoa(t.list[c].stocknum,str_stocknum,10);
                  gcvt(t.list[c].price,4,str_price);
                  itoa(t.list[c].quantity,str_quantity,10);

                  //*** Save to file ***
                  fputs(str_stocknum,stockfile);
                  fputs(spacer,stockfile);
                  fputs(t.list[c].description,stockfile);
                  fputs(spacer,stockfile);
                  fputs(str_price,stockfile);
                  fputs(spacer,stockfile);
                  fputs(str_quantity,stockfile);
                  //*** Check for end of line ***
                  if(count>1)
                        {
                        fputc('\n',stockfile);
                        count--;
                        }
                  //*** Terminate program ***
                    // exit(0);
                  }
            }
      }
      //*** Terminate program ***
      exit(0);
      //*** Close file ***
      fclose(stockfile);
}
//*** Get stock details from keyboard ***
int GetStockDetails(StockDetails& sd,StockTable& t)
{
      char string[11];

      //*** Enter & validate the Stock number ***
      cout<<"Enter Stock number : ";
      do
      {
            cin>>string;
            //*** Check first char for number ***
            while(!isdigit(string[0]) && string[0] != '-')
            {
                  clrscr();
                  cout<<"\nInvalid input : Must be 9 digit number\n";
                  cout<<"\nPlease re-enter Stock number : ";
                  cin>>string;
            }
      }
      //*** Repeat until a number is entered **
      while(!isdigit(string[0]) && string[0] != '-');
      //*** Convert string to an integer value ***
      sd.stocknum = atoi(string);
      //*** If Stock number not a 9 digit number ***
      while(sd.stocknum<100000000l || sd.stocknum>999999999l)
      {
            clrscr();
            cout<<"\nInvalid input : Must be 9 digit number\n";
            cout<<"\nPlease re-enter Stock number : ";
            cin>>sd.stocknum;
      }
      if(IsAt(sd.stocknum,t)!=NOTFOUND ||IsFull(t))
            return 0;

      cout<<"\nEnter item description : ";
      gets(sd.description);

      //*** Enter & validate price ***
      cout<<"\nEnter item price : ";
      do
      {
            cin>>string;
            //*** Check first char for number ***
            while(!isdigit(string[0]) && string[0] != '-')
            {
                  cout<<"\nInvalid input :\n";
                  cout<<"\nPlease re-enter price : ";
                  cin>>string;
            }
      }
      //*** Repeat until a number is entered **
      while(!isdigit(string[0]) && string[0] != '-');
      //*** Convert string to an integer value ***
      sd.price = atoi(string);
      //*** If Catalogue number not a 9 digit number ***
      while(sd.price<0)
      {
            cout<<"\nInvalid input : Must be above zero\n";
            cout<<"\nPlease re-enter price : ";
            cin>>sd.price;
      }

      //*** Enter & validate quantity ***
      cout<<"\nEnter item quantity : ";
      do
      {
            cin>>string;
            //*** Check first char for number ***
            while(!isdigit(string[0]) && string[0] != '-')
            {
                  cout<<"\nInvalid input : Must be numeric\n";
                  cout<<"\nPlease re-enter quantity : ";
                  cin>>string;
            }
      }
      //*** Repeat until a number is entered **
      while(!isdigit(string[0]) && string[0] != '-');
      //*** Convert string to an integer value ***
      sd.quantity = atoi(string);
      //*** If Catalogue number not a 9 digit number ***
      while(sd.stocknum<0)
      {
            cout<<"\nInvalid input : Must be above zero\n";
            cout<<"\nPlease re-enter price : ";
            cin>>sd.price;
      }
      return 1;
}

//*** Display specified record ***
void DisplayRecord(int key, StockTable& t)
{
      //*** Validate key ***
      while(key<100000000l || key>999999999l)
      {
            clrscr();
            cout<<"\nInvalid input : Must be 9 digit number\n";
            cout<<"\nPlease re-enter Catalogue number : ";
            cin>>key;
      }

      int post;
      //*** Find key position & display ***
      if((post=IsAt(key,t))!=NOTFOUND)
      {
            clrscr();
            cout<<t.list[post].stocknum
                   <<setw(25)<<t.list[post].description
                   <<setw(15)<<t.list[post].price<<setw(15)
                   <<t.list[post].quantity<<endl;
      }
}

//*******************************************
//*** End hash table function definitions ***
//*******************************************

void OpenFile(StockTable& t)
{
      StockDetails sd;
      FILE *stockfile;
      char *stocknum_ptr;
      char *description_ptr;
      char *price_ptr;
      char *quantity_ptr;
      char start[50];
      char *endptr;

      stockfile = fopen("C:\\Stock.txt","r+t");
      if(!stockfile)
      {
            cout<<"\nERROR : File not found\n";
            getch();
            exit(1);
      }
      while(fgets(start,50,stockfile)!=NULL)
      {
            stocknum_ptr = strtok(start,"\t\t");
            sd.stocknum = strtol(stocknum_ptr,&endptr,10);
            strcpy(sd.description,description_ptr=strtok(NULL,"\t\t"));
            price_ptr = strtok(NULL,"\t\t");
            sd.price = (strtod(price_ptr,&endptr));
            quantity_ptr = strtok(NULL,"\t\t");
            sd.quantity = atoi(quantity_ptr);
            Add(sd,t);
      }
      fclose(stockfile);
}

//**************************************
//*** Main menu function definitions ***
//**************************************

//*** Display menu ***
int DisplayMenu(char* text)
{
      int c, total;

      //*** Display menu ***
      clrscr();
      cout<<"MAIN MENU\n";
      cout<<text;

      //*** count number of options in menu ***
      for(c=0, total=0; c<strlen(text); c++)
            if(text[c]=='\n')
                  total++;
      //*** return number of options ***
      return total;
}

//*** Get user option ***
int GetOption(int max)
{
      char string[11];
      int opt;

      //*** Get user option ***
      cout<<"\nEnter option : ";
      do
      {
            cin>>string;
            //*** Check first char for number ***
            while(!isdigit(string[0]) && string[0] != '-')
            {
                  cout<<"\nInvalid option : Number must be between 1 and 7\n";
                  cout<<"\nPlease re-enter : ";
                  cin>>string;
            }
      }
      //*** Repeat until a number is entered **
      while(!isdigit(string[0]) && string[0] != '-');
      //*** Convert string to an integer value ***
      opt = atoi(string);

      //*** Reject invalid entries and re-enter ***
      while(opt<1||opt>max)
      {
            cout<<"\nInvalid option : Number must be between 1 and 7\n";
            cout<<"\nPlease re-enter : ";
            cin>>opt;
      }

      //*** return valid option ***
      return opt;
}

void ExecuteOption(int opt, StockTable& t)
{
      StockDetails sd;
      int key;
      char string[11];

      switch(opt)
      {
            case 1 : //*** Create empty table ***
                              clrscr();
                              CreateTable(t);
                              cout<<"Empty Table created!\n";
                              cout<<"\nPress any key to go to Main Menu\n";
                              getch();
                              return;

            case 2 : //*** Add new Record ***
                              clrscr();
                              GetStockDetails(sd,t);
                              if(!Add(sd,t))
                              {
                                    cout<<"\nERROR : Record already exists\n";
                                    cout<<"\nPress any key to go to Main Menu\n";
                                    getch();
                                    return;
                              }
                              char select;
                              while(select=='Y'||select!='y')
                              {
                                    clrscr();
                                    cout<<"New stock item entered\n";
                                    cout<<"\nDo you wish to add another stock item : [Y/N] : ";
                                    cin>>select;
                                    if(select=='N'||select=='n')
                                          return;
                                    clrscr();
                                    GetStockDetails(sd,t);
                                    if(!Add(sd,t))
                                          cout<<"\nERROR : Stock number already exists\n";
                              }
                              cout<<"\nPress any key to go to Main Menu\n";
                              getch();
                              return;

                               case 3 : //*** Delete specified record ***
                              clrscr();
                              cout<<"Enter Stock number of item to be removed : ";
                              do
                              {
                                    cin>>string;
                                    //*** Check first char for number ***
                                    while(!isdigit(string[0]) && string[0] != '-')
                                    {
                                          clrscr();
                                          cout<<"\nInvalid input : Must be 9 digit number\n";
                                          cout<<"\nPlease re-enter Stock number : ";
                                          cin>>string;
                                    }
                              }
                              //*** Repeat until a number is entered **
                              while(!isdigit(string[0]) && string[0] != '-');
                              //*** Convert string to an integer value ***
                              key = atoi(string);
                              while(key<100000000l || key>999999999l)
                              {
                                    clrscr();
                                    cout<<"\nPlease re-enter Stock number : ";
                                    cin>>key;
                              }
                              if(!Delete(key,t))
                              {
                                    cout<<"\nERROR : Record does not exist\n";
                                    getch();
                              }
                              else
                              {
                                    DisplayRecord(key,t);
                                    cout<<"\nAre you sure you wish to delete this item : [Y/N] : ";
                                    char select;
                                    cin>>select;
                                    if(select=='Y'||select=='y')
                                    {
                                          DisplayRecord(key,t);
                                          cout<<"\nItem removed\n";
                                          getch();
                                    }
                                    char choice;
                                    do
                                    {
                                          clrscr();
                                          cout<<"Do you wish to delete another stock item [Y/N] : ";
                                          char choice;
                                          cin>>choice;
                                          if(choice=='N'||choice=='n')
                                                return;
                                          clrscr();
                                          cout<<"Enter Catalogue number of item to be removed : ";
                                          do
                                          {
                                                cin>>string;
                                                //*** Check first char for number ***
                                                while(!isdigit(string[0]) && string[0] != '-')
                                                {
                                                      clrscr();
                                                      cout<<"\nInvalid input : Must be 9 digit number\n";
                                                      cout<<"\nPlease re-enter Catalogue number : ";
                                                      cin>>string;
                                                }
                                          }
                                          //*** Repeat until a number is entered **
                                          while(!isdigit(string[0]) && string[0] != '-');
                                          //*** Convert string to an integer value ***
                                          key = atoi(string);
                                          while(key<100000000l || key>999999999l)
                                          {
                                                clrscr();
                                                cout<<"\nInvalid input : Must be 9 digit number\n";
                                                cout<<"\nPlease re-enter Catalogue number : ";
                                                cin>>key;
                                          }
                                          if(!Delete(key,t))
                                          {
                                                cout<<"\nERROR : Record does not exist\n";
                                                getch();
                                          }
                                          else
                                          {
                                                DisplayRecord(key,t);
                                                cout<<"\nAre you sure you wish to delete this item : [Y/N] : ";
                                                char select;
                                                cin>>select;
                                                if(select=='Y'||select=='y')
                                                {
                                                      clrscr();
                                                      cout<<"\nItem removed\n";
                                                      getch();
                                                }
                                          }
                                    }
                                    while(choice!='N'||choice!='n');
                              }
                               cout<<"\nPress any key to go to Main Menu\n";
                              getch();
                              return;
                              case 4 : //*** Display contents of table ***
                              clrscr();
                              DisplayTable(t);
                              getch();
                              return;
                              case 5 : //*** Update specified record ***
                              clrscr();
                              cout<<"Enter Stock number of product to be updated : ";
                              do
                              {
                                    cin>>string;
                                    //*** Check first char for number ***
                                    while(!isdigit(string[0]) && string[0] != '-')
                                    {
                                          clrscr();
                                          cout<<"\nInvalid input : Must be 9 digit number\n";
                                          cout<<"\nPlease re-enter Catalogue number : ";
                                          cin>>string;
                                    }
                              }
                              //*** Repeat until a number is entered **
                              while(!isdigit(string[0]) && string[0] != '-');
                              //*** Convert string to an integer value ***
                              key = atoi(string);
                              while(key<100000000l || key>999999999l)
                              {
                                    clrscr();
                                    cout<<"\nInvalid input : Must be 9 digit number\n";
                                    cout<<"\nPlease re-enter Catalogue number : ";
                                    cin>>key;
                              }
                              if(!Retrieve(key,t,sd))
                              {
                                    cout<<"\nRecord not found\n";
                                    getch();
                              }
                              else
                              {
                                    DisplayRecord(key,t);
                                    cout<<"\n\nEnter new description : ";
                                    gets(sd.description);
                                    cout<<"\nEnter new price : ";
                                    cin>>sd.price;
                                    cout<<"\nEnter new quantity : ";
                                    cin>>sd.quantity;
                                    Update(sd,t);
                              }

                              cout<<"\nPress any key to go to Main Menu\n";
                              return;

                              case 6 : //*** Display specified record ***
                              clrscr();
                              cout<<"Enter Stock number of item to be retrieved : ";
                              do
                              {
                                    cin>>string;
                                    //*** Check first char for number ***
                                    while(!isdigit(string[0]) && string[0] != '-')
                                    {
                                          clrscr();
                                          cout<<"\nInvalid input : Must be 9 digit number\n";
                                          cout<<"\nPlease re-enter Stock number : ";
                                          cin>>string;
                                    }
                              }
                              //*** Repeat until a number is entered **
                              while(!isdigit(string[0]) && string[0] != '-');
                              //*** Convert string to an integer value ***
                              key = atoi(string);
                              while(key<100000000l || key>999999999l)
                              {
                                    clrscr();
                                    cout<<"\nInvalid input : Must be 9 digit number\n";
                                    cout<<"\nPlease re-enter Stock number : ";
                                    cin>>key;
                              }

                              DisplayRecord(key,t);
                               /*     if(!PurchaseStock(key,t))
                              {
                                    cout<<"\nRecord not found\n";
                                    cout<<"\nPress any key to go to Main Menu\n";
                                    getch();
                                    return;
                              }      */
                              cout<<"\nPress any key to go to Main Menu\n";
                              getch();
                              return;
                              case 7 : //*** Terminate program ***
                              clrscr();
                              Terminate(t);
                              cout<<"Data now saved to disk\n";
                              cout<<"\nPROGRAM TERMINATED\n";
                              getch();
                              break;
      }
}




Also here is a copy of the contents of the Stock.txt file:

830722442            Electric shower       59.95       20      
431032562            Square lantern                  14.99            15
830455762            Bathroom cabinet            21.99            45
256051744            Quartz carraige clock            13.95            50
255700116            Repeater alarm clock             8.95            45
610467001            Midi Hi-fi trolley            24.99            13
645473973            Lounge unit                   139.99            5
415328351            Air purifier                   9.95            29
430599079            Table lamp                  31.99            47      
415262433            Fuel effect fire            59.95            14
830303978            Shower heater                  84.95            21
610478056            Directors chair                  19.99            28
255899002            Hexagonal lantern clock            24.95            38
255999905            Pandant barometer            16.95            23
256065844            Travel alarm clock             4.95            60
256013917            Grandfather clock             625.00            2
830339027            Shower screen                      21.99           24
257001918            Grandmother clock             495.00            2
415321444            Upright fan heater            19.75            30
610407231            Multi-purpose trolley            14.99            35
415402439            Room ioniser                  39.50            36
415413429            Oscillating fan heater            29.50            50
425103737            Desk fan                  28.95            40
640822820            Modern hall table            29.99            18
830654813            Linen bin                  16.99            18
430235714            Double spot standard lamp      24.99            27
430987969            Remote dimmer switch            24.99            12
430187793            Anglepoise lamp                  17.99            35
830680900            Shower rail                   9.99            20
430979011            Ceiling fan                  74.99            12
610455372            Tier shelf unit                  29.99            34
415419603            Convector heater            31.45            20
431034988            Panelled glass shade            12.99            50
830716948            Bathroom scale                  14.99            20
830616070            Bath/Shower mixer            14.99            11
430761240            Dimmer switch                   4.99            45
830608121            Natural pine mirror             8.49            35
640821134            Curved mirror                  19.99            30
610721345            Occasional table            24.99            20
255007422            Quartz clock                   5.95            55
610754329            Nest of tables                  34.99            25
645141925            Sofa bed                  99.99            10
415329036            Thermo tube                  11.45            55
255597926            Quartz presentation clock      49.95            24
255623910            Marine clock                  19.95            15
430648761            Wall light                  19.99            58
415363087            Fan heater                  25.95            38
431039412            Ceiling spotlight             9.99            25
830663415            Power shower                  99.95            20
415325241            Log effect fire                  45.95            21
Avatar of Kent Olsen
Kent Olsen
Flag of United States of America image


Hi Knoxy,


I assume that the Borland 4.x environment that you're using includes their IDE.  They really do have wonderful development and debugging environments.

I'd start this up in the IDE, and use the F-keys to step through the code.

F9 - run.
F8 - step 1 line (does not enter embedded functions).
F7 - step 1 line (step into your function calls).


Good Luck,
Kdo
ASKER CERTIFIED SOLUTION
Avatar of substand
substand

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of substand
substand

the input file as you posted it didn't contain tabs, they were spaces.

that is the problem i was having in my last response.


after fixing that, it appears the problem is solved.  but you have formatting errors when showing stocks that you'll need to fix.
Avatar of Knoxy

ASKER

Hi guys,

I have tried all of the above and I'm still getting the same problems, I'm literally pulling my hair out!

Any other suggestions guys? have you tried copying and pasting the code to see how it looks in your compiler?

Substand:

Regarding the input file you are talking about when you say it didnt contain tabs, they were spaces. I see what you mean as when I opened the file after running it thru Borland 4.5 compiler everything in the text file is joined up. How can I remedy this problem? how do I get the file in a tabbed column format?

Thanks for your help so far guys.


No comment has been added lately, so it's time to clean up this TA. I will
leave a recommendation in the Cleanup topic area that this question is:

Answered: Points to substand: Grade A

Please leave any comments here within the next seven days.

Experts: Silence means you don't care. Grading recommendations are made in light
of the posted grading guidlines (https://www.experts-exchange.com/help.jsp#hi73).

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

-bcl (bcladd)
EE Cleanup Volunteer