Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am creating an application to keep track of a bookstore inventory. It will take the filepath to a text file containing the information as an argument to main. The problem I am having seems to be whenever I attempt to access an element of the class state vector inventory that I am using to store my Item objects. First is the class header, followed by the method definitions, and then the main. Thanks in advance.

    #ifndef _BOOKSTORE_H_
    #define _BOOKSTORE_H_

    #include <vector>
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <sstream>
    #include <algorithm>
    #include <iterator>
    #include <stdlib.h>

    #include "Item.h"
    #include "Paperback.h"
    #include "Hardcover.h"
    #include "Audiobook.h"
    #include "Ebook.h"

    using namespace std;

    class Bookstore {

    //States
    private:
        vector<Item*> inventory;
    //Behaviors
    public: 
        Bookstore();
        void loadInventory(const char*);
        void searchInventory(string);
        unsigned int inventorySize();
        void printInventory();
        vector<string> split(string);

    };

    #endif


    #include "Bookstore.h"

    Bookstore::Bookstore() {}

    void Bookstore::loadInventory(const char* filepath) {

        string ty = "";
        string ti = "";
        string au = "";
        string pri = "";
        string f = "";
        string cd = "";
        string pro = "";

        string line;
        ifstream ifs;
        ifs.open (filepath);

        if (ifs.is_open()) {
            while (ifs.good()) {
                ty = "";
                ti = "";
                au = "";
                pri = "";
                f = "";
                cd = "";
                pro = "";

                getline(ifs, line);

                if (line.compare("Paperback") == 0) {
                    ty = "Paperback";
                    getline(ifs, line);
                    ti = line;
                    getline(ifs, line);
                    au = line;
                    getline(ifs, line);
                    pri = line;
                    Paperback p(ty, ti, au, pri);
                    inventory.push_back(&p);
                }

                if (line.compare("Hardcover") == 0) {
                    ty = "Hardcover";
                    getline(ifs, line);
                    ti = line;
                    getline(ifs, line);
                    au = line;
                    getline(ifs, line);
                    pri = line;
                    getline(ifs, line);
                    f = line;
                    Hardcover h(ty, ti, au, pri, f);
                    inventory.push_back(&h);
                }

                if (line.compare("Audio") == 0) {
                    ty = "Audio";
                    getline(ifs, line);
                    ti = line;
                    getline(ifs, line);
                    au = line;
                    getline(ifs, line);
                    pri = line;
                    getline(ifs, line);
                    cd = line;
                    Audiobook a(ty, ti, au, pri, cd);
                    inventory.push_back(&a);
                }

                if (line.compare("Electronic") == 0) {
                    ty = "Electronic";
                    getline(ifs, line);
                    ti = line;
                    getline(ifs, line);
                    au = line;
                    getline(ifs, line);
                    pri = line;
                    getline(ifs, line);
                    pro = line;
                    Ebook e(ty, ti, au, pri, pro);
                    inventory.push_back(&e);            
                }

            }
        }

        ifs.close();
        cout << inventory.size() << endl;

        for (unsigned int i=0; i<inventory.size(); i++) {
            inventory.at(i)->printItem();
        }
    }

    void Bookstore::searchInventory(string query) {

        vector<string> searchStr;
        int count;
        string currentStr;

            for (unsigned int i=0; i<inventory.size(); i++) {

                    currentStr = inventory.at(i)->getTitle();
                    searchStr = split(currentStr);

                    for(unsigned int j = 0; j < searchStr.size(); j++) {
                        if (searchStr[j].compare(query)==0) {
                            inventory.at(i)->printItem();
                            count++;
                        }
                    }

                    currentStr = inventory.at(i)->getAuthor();
                    searchStr = split(currentStr);

                    for(unsigned int j = 0; j < searchStr.size(); j++) {
                        if (searchStr[j].compare(query)==0) {
                            inventory.at(i)->printItem();
                            count++;
                        }
                    }

                    if ((i==(inventory.size()-1))&&(count==0)) {
                        cout << "Sorry, no matching results were found." << endl;
                    } else if ((i==(inventory.size()-1))&&(count!=0)) {
                        cout << "Query complete." << endl;
                    }
            }
    }

    unsigned int Bookstore::inventorySize() {
        unsigned int num = inventory.size();
        return num;
    }

    void Bookstore::printInventory() {
        for (unsigned int i = 0; i < inventory.size(); i++) {
            inventory.at(i)->printItem();       
        }

    }

    vector<string> Bookstore::split(string s) {
        vector<string> pieces;
        istringstream iss(s);
        copy(istream_iterator<string>(iss), istream_iterator<string>(),
            back_inserter<vector<string> >(pieces));

        return pieces;
    }

    #include "Bookstore.h"

    int main(int argc, char** argv) {

        Bookstore current;

        if (argc==2) {
            current.loadInventory(argv[1]);
        }

        cout << current.inventorySize() << endl;

        //Initialize variables
        char status = 'R';
        string input = "";
        int iter = 1;

        //Run application until quit
        while (status=='R') {

            //Provide menu
            if (iter==1) {
                cout << "Welcome to Bookstore Inventory 9000." << endl;
            }

            if (current.inventorySize()==0) {
                    cout << "There are no entries!" << endl;
                    status = 'Q';
            } else {

                cout << "Would you like to (V)iew all, (S)earch, or (Q)uit?" << endl;

                getline(cin, input);

                if (input.compare("V")==0) {
                    current.printInventory();       
                } else if (input.compare("S")==0) {
                    cout << endl;
                    cout << "What are you looking for?" << endl;
                    getline(cin, input);
                    current.searchInventory(input);
                    cout << endl;
                } else if (input.compare("Q")==0) {
                    status = 'Q';
                    cout << "Thank you for perusing our inventory. Goodbye." << endl;
                } else {
                    cout << endl;
                    cout << "This is not a valid choice. Please try again." << endl;
                    cout << endl;
                }
            }

            iter++;

        }

    return -1;

    }
share|improve this question
 
You should reduce the amount of code you have to the smallest amount that demonstrates the problem you're having. Also, we need to know what at is failing. –  CrazyCasta Oct 1 '12 at 8:31
add comment

1 Answer

Your problem is not with at(). Your problem is that you're storing away an address to a local variable, and then later you're using that pointer, even though the local variable doesn't exist anymore.

Specifically, in loadInventory, here's one example:

 if (line.compare("Paperback") == 0) {
                ty = "Paperback";
                getline(ifs, line);
                ti = line;
                getline(ifs, line);
                au = line;
                getline(ifs, line);
                pri = line;
                Paperback p(ty, ti, au, pri);
                inventory.push_back(&p);
            }

Note in the second-to-last line how you create a local (stack) variable named "p". In the last line, you take the address of that local variable and store it away. Once the code hits that final brace in the above quote, the variable named "p" goes away, and that pointer in your vector is no good anymore.

One possible solution is to dynamically allocate:

Paperback* p = new Paperback(ty, ti, au, pri);
inventory.push_back(p);

Note that if you do this, you'll have to delete those pointers yourself once your inventory vector is done with them.

share|improve this answer
 
So apparently i'm too new to even upvote you but my god, sir, you just made my night. With 5 minutes to spare on a midnight deadline, that was exactly what I had overlooked and the only thing wrong with my code. Threw in a couple news and destructors accordingly and everything worked. Can I buy you a drink? Seriously. Thank you. –  image_engineer Oct 1 '12 at 3:59
 
Glad I could help. –  Tom W Oct 1 '12 at 4:34
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.