std::vector? updated

Since you have a running program, you only need to change the private variables in the header files and the code in the cpp files for the primary indexes so they use a dynamic array or vector instead. For the primary index, the initial vector size will be 8. The non-menu-driven conversion program will report nothing to the user. When the vector needs to change size upward, you will double its size. Note: since the indexes can store the number of records in its auxiliary file, you can start the vector at that size (or slightly larger) when you start the menu-based program


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
#ifndef MY_PRIMARY_INDEX_H
#define MY_PRIMARY_INDEX_H
#include <string>
#include <cstring>
#include <iostream>
#include <fstream>
#include <vector>

class PrimaryIndex
{
private:
    struct Entry
    {
        //The key is the entry title
        std::string key;
        //the value is the position in the binary file that the indexed entry is located
        int value;

        Entry() : value(-1) {}
        Entry(const std::string& k, int v) : key(k), value(v) {}
    };

    std::vector<Entry> index;

public:
    //default constructor
    PrimaryIndex()
        : index.size(0)
    {
        this->resize(this->index.size);
    }

    void add_index(const std::string&, int);
    void remove_index(const std::string&);
    int get_value(const std::string&) const;

    int get_count() const;

    void load(const std::string&);
    void save(const std::string&) const;
};
#endif


cpp 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
#include "PrimaryIndex.h"
#include<vector>



void PrimaryIndex::add_index(const std::string& key, int value)
{
    //Check if index already exists, as no duplicates are allowed
    for(int i = 0; i < count; i++)
    {
        if(index[i].key == key)
        {
            std::cerr << "Cannot add index, already exists." << std::endl;
            return; //early return from function, can't do anything
        }
    }

    //Otherwise, add it to the end
    if(count < 25)
    {
        int pos = count;

        index[pos] = PrimaryIndex::Entry(key, value);

        count++;

    }
    else
    {
        std::cerr << "Cannot add index, index full." << std::endl;
    }
}

void PrimaryIndex::remove_index(const std::string& key)
{
    //search for matching key
    for(int i = 0; i < count; i++)
    {
        //check if key matches
        if(index[i].key == key)
        {
            //Move index entries after the remove one forward
            //to fill the gap
            for(int j = i; j < count - 1; j++)
            {
                index[j] = index[j + 1];
            }

            count--;

            return;
        }
    }

    std::cerr << "Cannot remove index, does not exist" << std::endl;
}

int PrimaryIndex::get_value(const std::string& key) const
{
    for(int i = 0; i < count; i++)
    {
        if(index[i].key == key)
        {
            return index[i].value;
        }
    }

    //Indicates not found
    return -1;
}

int PrimaryIndex::get_count() const
{
    return this->count;
}

void PrimaryIndex::load(const std::string& filename)
{

    count = 0;

    std::ifstream inFile(filename.c_str());

    while(inFile.good() && !inFile.eof())
    {
        PrimaryIndex::Entry entry;

        inFile >> entry.key >> entry.value;

        index[count++] = entry;
    }
}

void PrimaryIndex::save(const std::string& filename) const
{
    std::ofstream outFile(filename.c_str());

    for(int i = 0; i < count && outFile.good(); i++)
    {
        outFile << index[i].key << ' '
                << index[i].value << std::endl;
    }
}

Last edited on
Why don't you tell us what the assignment is. In you last thread you asked what kind of dynamic array or vector could be used. The std::vector fits that bill. You are on the right track here, but there are some syntax errors that need to be cleaned up.

However, you now ask to not use std::vector. It sounds like that may be an assumption in the assignment, which is fine, but there is some ambiguity in what you are asking.

The quick answer is to make index an Entry* and in the constructor do index = new Entry[8];. I think. Based on my understanding of your question. But without better understanding exactly what you are asking, I can't be certain that's what you want.
I just edited my first post with the instructions I was given.
Got it. The original file had struct Entry { ... } [25];. Now we want the size of the array to change dynamically.

First, go back to the original code you started with. The std::vector suggestion doesn't fit within the parameters of the assignment. (Sorry about that--I didn't know.)

Instead of statically allocating 25 Entries, create a pointer to an array of entries, and allocate the array in the constructor.

1
2
3
4
5
6
...
struct Entry{ ... };
Entry* index;
...
PrimaryIndex::PrimaryIndex() : index(new Entry[8]), count(0) {}
...


You will need to keep track of the current size of the Entry array. When you are adding an entry and you exceed your capacity, you need to:
1. Allocate a new array twice the current size
2. Copy all of the elements from the original array to the new one.
3. Delete the original array.
4. Insert the new entry as normal
Thanks for your help. I finished it and turned in the assignment yesterday. :)
Topic archived. No new replies allowed.