Hash Table not reading last line of txt file

I was assigned to create a chained hash table using a vector of vectors. It is designed to hold objects of type Entry. I have written all of the functions and the constructor but when I try to use the constructor that reads an input and then output it back to me in order of keys, whichever string was on the last line of the .txt file its reading from is gone. I think its a problem with my constructor because when I try to use get to get that specific value from the table before printing it its gone. I was hoping for some insight to where I might be going wrong from someone with a little more experience. Thanks. Heres my code:

Entry Header File:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#ifndef entry_h
#define entry_h

// entry.h - defines class Entry            


#include <string>
#include <iosfwd>

class Entry {

public:
    // constructor                                          
    Entry(unsigned int key = 0, std::string data = "");

    // access and mutator functions                         
    unsigned int get_key() const;
    std::string get_data() const;
    static unsigned int access_count();
    void set_key(unsigned int k);
    void set_data(std::string d);

    // operator conversion function simplifies comparisons  
    operator unsigned int () const;

    // input and output friends                             
    friend std::istream& operator>>
    (std::istream& inp, Entry &e);
    friend std::ostream& operator<<
    (std::ostream& out, Entry &e);

private:
    unsigned int key;
    std::string data;
    static unsigned int accesses;
};

#endif /* entry_h */ 


Table header file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//
//  table.h
//  
//
#ifndef table_h
#define table_h

#include <string>
#include <vector>
#include <algorithm>
#include "entry.h"

using namespace std;

class Table {

 public:
  Table(unsigned int max_entries = 100);
  //Builds empty table to hold 100 entries
  Table(unsigned int entries, std::istream& input);
  //Builds table to hold entries, reads and puts them 1 at a time
  ~Table();
  //Destructor
  void put(unsigned int key, std::string data);
  //Creates new entry for the table
  //Updates if key is used
  void put(Entry e);
  //Creates a copy of e in the table
  string get(unsigned int key) const;
  //Returns string associated with key
  //Returns empty string if key isnt used
  bool remove(unsigned int key);
  //Removes entry in given key
  //Returns true of removed, false of no entry
  int find(Entry e);
  //index in second array that e exists, 0 if not found
  friend std::ostream& operator<< (std::ostream& out, const Table& t);
  //Prints each entry in the table in order of their key


 private:
  int size;
  int num_entries;
  unsigned int hashkey(unsigned int key) const;

  vector<vector<Entry> > A;
};

#endif /* table_h */ 



Table Implementation File:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//table.cpp

#include<iostream>
#include<vector>
#include<algorithm>
#include "table.h"

using namespace std;


Table::Table(unsigned int max_entries){
  max_entries = 100;
  size = max_entries * 2;
  A.resize(size);
}

Table::Table(unsigned int entries, std::istream& input){
  size = entries*2;
  A.resize(size);
  num_entries = entries;
  Entry temp;
  for (size_t i = 0; i < entries; i++) {
    input >> temp;
    put(temp);
  }
}

/*
Table::~Table() {
  for (int i = 0; i <size; i++) {
    for (int j = 0; j < A[i].size(); j++) {
      delete A[i][j];
    }
  }
  }*/

Table::~Table() {
  A.clear();
}

void Table::put(unsigned int key, std::string data){
  Entry e;
  e.set_key(key);
  e.set_data(data);
  put(e);
  num_entries++;
}

void Table::put(Entry e) {
  /*if (!A[hashkey(e.get_key())].empty()) {
  // if (find(e) != 0) {
    for(int i = 0; i < A[hashkey(e.get_key())].size(); i++) {
      if(A[hashkey(e.get_key())][i].get_key() == e.get_key()){
    A[hashkey(e.get_key())][i] = e;
    return;
      }
    }
  }
  else {
    A[hashkey(e.get_key())].push_back(e);
    num_entries++;
    }*/

  if (A[hashkey(e.get_key())].empty()) {
    A[hashkey(e.get_key())].push_back(e);
    }
  else {
    for(size_t i = 0; i < A[hashkey(e.get_key())].size(); i++) {
    if (A[hashkey(e.get_key())][i].get_key() == e.get_key()) {
      remove(A[hashkey(e.get_key())][i].get_key());
      break;
    }
      }
   A[hashkey(e.get_key())].push_back(e);
  } 
}

string Table::get(unsigned int key) const {
  if( A[hashkey(key)].size() == 0) {
    return "";
  }
  else {
    for (size_t i = 0; i < A[hashkey(key)].size(); i++) {
      if (A[hashkey(key)][i].get_key() == key) {
    return A[hashkey(key)][i].get_data();
      }
      else {
    return "";
      }
    }
  }
}

bool Table::remove(unsigned int key) {
  for (size_t i = 0; i < A[hashkey(key)].size(); i++) {
    if (A[hashkey(key)][i].get_key() == key) {
    swap(A[hashkey(key)][i],A[hashkey(key)][A[hashkey(key)].size() - 1]);
    A[hashkey(key)].pop_back();
    num_entries--; 
        return true;
      }
      else {
    return false;
      }
  }
}

int Table::find(Entry e) {
  for (size_t i = 0; i < A[hashkey(e.get_key())].size(); i++) {
      if (A[hashkey(e.get_key())][i] == e) {
    return i;
      }
      else {
    return 0;
      }
  }
}

ostream& operator << (ostream& out, const Table& t) {
  vector<Entry> order;
  for(size_t i = 0; i < t.A.size(); i++) {
    for (size_t j = 0; j < t.A[i].size(); j++) {
      order.push_back(t.A[i][j]);
    }
  }
  sort(order.begin(), order.end());
  for(Entry k: order) {
    out << k << endl;
  }
  return out;
}

unsigned int Table::hashkey(unsigned int key) const{
  const double c = 1.61803;
  // return key % size;
  return (int)(size*((key * c) - (int)(key * c)));
}


Thanks


Last edited on
table.cpp

line 12: Why are you changing the passed argument?

Lines 22-25: Why are you using a for loop? This presumes you know how many entries are in the file in advance. Not a very generalized solution.

Line 23: You don't check that the read succeeded.

Line 111,114: What's to distinguish a not found (0) from the first entry (0)?

Since you haven't shown the code for Entry's overloaded input operator, I can't tell if that is correct. My hunch is that it is not.

Line 12: It supposed to be the default constructor that sets the table size to 100, but I kept getting an error so I moved it into the function.

Line 22-25: The number of entries is specified by the user beforehand. Its not that generalized but that function definition was given is required for it to pass the automated tests.

And for the find function I dont use it anywhere I originally wrote it as a helper function and didnt end up using it. I just forgot to take it out.

Here is the code for Entry's input operator:
1
2
3
4
5
6
7
8
9
istream& operator>> (istream& inp, Entry &e) {
    inp >> e.key;
    // get data in two parts to handle white space          
    string first_word, rest_of_line;
    inp >> first_word;
    getline(inp, rest_of_line);
    e.data = first_word + rest_of_line;
    return inp;
}


The input operator should be correct entry.h and entry.cpp were given as part of the assignent.
Last edited on
Line 12: Your constructor declaration with the default value is correct. You should delete line 12.

Line 23: I'll repeat that you don't check if the input operation was successful. If the input file is short, you won't detect it and will put(temp) even if you didn't read anything.
Could you show us the input file and entry.cpp + main.cpp so we can compile and run it.
Topic archived. No new replies allowed.