哈希表从文件中读取

时间:2015-11-17 06:30:40

标签: c++ hashtable

对于我的项目,我需要创建一个哈希表,其中包含库存信息。我认为我有大部分需要做的工作,但我有一个问题是填写哈希表,信息形成一个文本文件。当文件为空时我的程序启动并正确显示菜单,但是当我将信息放入文本文件时,它会永远冻结,直到Putty杀死程序。此外,当我尝试添加股票时,它似乎没有正确地获取信息,这可能是它永远从文件中读取的原因。我已经尝试过处理文件中的一些事情,但没有任何对我有用。

编辑: 在添加了一些cout语句后,我发现在循环中"而(!in.eof())" 是无限的,永远不会到达文件的末尾,我不知道为什么。

hashTable.cpp:

#include "hashtable.h"
#include <iostream>
#include <fstream>
#include<cstring>
using namespace std;

void hashTable::initializeTable()
{
        table = new node*[capacity];

        int i;
        for(i=0; i<capacity; i++)
                table[i] = NULL;
}

hashTable::hashTable() : capacity(DEFAULT_CAPACITY), size(0)
{
        initializeTable();
}

hashTable::hashTable(char * fileName) : capacity(DEFAULT_CAPACITY), size(0)
{
        ifstream in;
        data currData;
        char tickerSymbol[100];
        char name[100];
        float netVal;
        char date[100];
        float yToD;

        initializeTable();

        in.open(fileName);
        if(!in)
        {
                cerr << "fail to open " << fileName << " for input!" << endl;
                return;
        }

        in.get(tickerSymbol, 100, ';');
        while(!in.eof())
        {
                in.ignore(100, ';');
                in.get(name, 100, ';');
                in.ignore(100, ';');
                in.ignore(100, ';');
                in >> netVal;
                in.ignore(100, ';');
                in.get(date, 100, ';');
                in.ignore(100, ';');
                in >> yToD;
                in.ignore(100, '\n');

                currData.setTickerSymbol (tickerSymbol);
                currData.setName (name);
                currData.setNetValue(netVal);
                currData.setDate(date);
                currData.setYToD(yToD);

                insert(currData);

                in.get(tickerSymbol, 10, ';');
        }
        in.close ();
}

hashTable::hashTable(const hashTable& aTable):capacity(aTable.capacity), size(aTable.size)


{
        table = new node*[capacity];

        int i;
        for(i=0; i<capacity; i++)
        {
                if (aTable.table[i] == NULL)
                        table[i] = NULL;
                else
                {
                        table[i] = new node(aTable.table[i]->item);

                        node * srcNode = aTable.table[i]->next;
                        node * destNode = table[i];
                        while(srcNode)
                        {
                                destNode->next = new node(srcNode->item);
                                destNode = destNode->next;
                                srcNode = srcNode->next;
                        }
                        destNode->next = NULL;
                }
        }
        }

const hashTable& hashTable::operator= (const hashTable& aTable)
{
        if(this == &aTable)
                return *this;
        else
        {
                destroyTable();

                table = new node*[capacity];
                capacity = aTable.capacity;
                size = aTable.size;

                int i;
                for(i=0; i<capacity; i++)
                {
                        if (aTable.table[i] == NULL)
                                table[i] = NULL;
                        else
                        {
                                table[i] = new node(aTable.table[i]->item);

                                    node * srcNode = aTable.table[i]->next;
                                node * destNode = table[i];
                                while(srcNode)
                                {
                                        destNode->next = new node(srcNode->item);
                                        destNode = destNode->next;
                                        srcNode = srcNode->next;
                                }
                                destNode->next = NULL;
                        }
                }
                return *this;
        }
}

void hashTable::destroyTable ()
{
        int i;
        for(i=0; i<capacity; i++)
        {
                node * head = table[i];
                node * curr;
                while(head)
   {
                        curr = head->next;
                        head->next = NULL;
                        delete head;
                        head = curr;
                }
        }

        delete [] table;
}
hashTable::~hashTable()
{
        destroyTable();
}

void hashTable::insert (const data& aData)
{
        char key[100];
        aData.getTickerSymbol(key);
        int index = calculateIndex(key);

        node * newNode = new node(aData);

 newNode->next = table[index];
        table[index] = newNode;
        size++;
}

bool hashTable::remove (char * key)
{
        int index = calculateIndex(key);

        node * curr = table[index];
        node * prev = NULL;
        char id[100];
        while (curr)
        {
                curr->item.getTickerSymbol (id);
                if(strcmp(key, id) == 0)
                {
                        if(!prev)
                                table[index] = curr->next;
                        else
                                prev->next = curr->next;

                        curr->next = NULL;
   delete curr;
                        size--;
                        return true;
                }
                else
                {
                        prev = curr;
                        curr = curr->next;
                }
        }
        return false;
}

bool hashTable::retrieve (char * key, data & aData)const
{
        int index = calculateIndex(key);

        node * curr = table[index];
        char id[100];
        while (curr)
        {
                curr->item.getTickerSymbol (id);
                if(strcmp(key, id) == 0)
 {
                        aData = curr->item;
                        return true;
                }
                else
                        curr = curr->next;
        }

        return false;
}

void hashTable::display (void)const
{
        int i;
        node * curr;

        cout << "Data in the table: " << endl << endl;
        for(i=0; i<capacity; i++)
        {
                for(curr = table[i]; curr; curr = curr->next)
                        cout << '\t' << curr->item << endl;
        }
}
int hashTable::getSize (void) const
{
        return size;
}

void hashTable::writeOut(char * fileName)
{
        ofstream out;

        out.open(fileName);
        if(!out)
        {
                cerr << "fail to open " << fileName << " for output!" << endl;
                return;
        }

        int i;
        char tickerSymbol[100];
        char name[100];
        node * curr;
        for(i=0; i<capacity; i++)
        {
                for(curr = table[i]; curr; curr = curr->next)
 {
                        curr->item.getTickerSymbol (tickerSymbol);
                        curr->item.getName (name);
                        out << tickerSymbol << ';' << name << ';' << curr->item.getNetValue () << '\n';
                }
        }
        out.close ();
}

int hashTable::calculateIndex (char * key)const
{
        char * c = key;
        int total = 0;
        while(*c)
        {
                total += *c;
                c++;
        }

        return total%capacity;
}     

的main.cpp

#include <stdlib.h>
//#include <crtdbg.h>


#include "hashtable.h"
#include <iostream>
using namespace std;

void displayMenu();
char getCommand();
void executeCmd(char command, hashTable& aTable);

void getStock(data & stock);
int getInt(char * prompt);
float getFloat(char * prompt);
void getString(char * prompt, char * input);

void display(const hashTable & aTable);

const int MAX_LEN = 100;

int main()
{
           char command = 'a';
        char fileName[] = "data.dat";
        hashTable stocks(fileName);

        displayMenu();
        command = getCommand();
        while(command != 'q')
        {
                executeCmd(command, stocks);
                displayMenu();
                command = getCommand();
        }

        stocks.writeOut (fileName);
        cout << "\nThank you for using CWMS!" << endl << endl;
        return 0;
}

void displayMenu()
{
        cout << "\nWelcome to CS Stock Management System! "<< endl;
        cout << "\ta> add a stock" << endl
                 << "\tr> remove a stock" << endl

       << "\ts> search for a stock" << endl
                 << "\tl> list all the stocks" << endl
                 << "\tq> quit the application" << endl << endl;
}

char getCommand()
{
        char cmd;
        cout << "Please enter your choice (a, r, s, l or q):";
        cin >> cmd;
        cin.ignore(100, '\n');
        return tolower(cmd);
}

void executeCmd(char command, hashTable& aTable)
{
        data stock;
        char key[MAX_LEN];

        switch(command)
        {
        case 'a': getStock(stock);
            aTable.insert (stock);
                          cout << endl << "the stock has been saved in the database. " << endl;
                break;
        case 'r': getString("\nPlease enter the ticker symbol of the stock you want to remove: ", key);
                      aTable.remove(key);
                          cout << endl << key << " has been removed from the database. " << endl;
                break;
        case 's': getString("\nPlease enter the ticker symbol of the stock you want to search: ", key);
                          aTable.retrieve (key, stock);
                          cout << endl << "Information about " << key << ": " << endl << '\t' << stock << endl;
                break;
        case 'l': display(aTable);
                break;
        default: cout << "illegal command!" << endl;
                break;
        }
}
void display(const hashTable & aTable)
{
        aTable.display();
}

void getStock(data & stock)
{
         char tickerSymbol[MAX_LEN];
         char name[MAX_LEN];
         float netVal;
         char date[MAX_LEN];
         float yToD;

         cout << "\nPlease enter information about the stock: " << endl;
         getString("\tticker symbol: ", tickerSymbol);
         getString("\tname: ", name);
         netVal = getFloat("\tnet asset value: ");
         getString("\tdate of that value: ", date);
         yToD = getFloat("\tyear to date return: ");

         stock.setTickerSymbol (tickerSymbol);
         stock.setName (name);
         stock.setNetValue (netVal);
         stock.setDate (date);
         stock.setYToD (yToD);
}
int getInt(char * prompt)
{
        int temp;
        cout << prompt;
        cin >> temp;
        while(!cin)
        {
                cin.clear ();
                cin.ignore(100, '\n');
                cout << "Illegal input -- try again: ";
                cin >> temp;
        }
        cin.ignore(100, '\n');
        return temp;
}
float getFloat(char * prompt)
{
        float temp;
        cout << prompt;
        cin >> temp;
        while(!cin)
        {
                cin.clear ();
                cin.ignore(100, '\n');
                cout << "Illegal input -- try again: ";
                cin >> temp;
        }
        cin.ignore(100, '\n');
        return temp;
}
void getString(char * prompt, char * input)
{
        cout << prompt;
        cin.get(input, MAX_LEN, '\n');
        cin.ignore (100, '\n');
}

1 个答案:

答案 0 :(得分:0)

没关系,我只是在我的data.dat文件的行尾没有分号,所以它永远不会到达终点。