1

I need to read a .txt file and use the first number as the array size in a function called getData.

In my code, I am able to read the file and assign it to the array size as listSize. I am also able to fill the rest of the array with the .txt information. When I print out what is in my array WITHIN the getData function, it works.

The problem is that when I try to access the array outside of the getData function my program crashes. I am new to pointers, and c++ in general. I don't think I am passing it or calling it correctly. I have had a hard time finding information to assist me in the problem.

How can I access the arrays I created in getData?

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>

using namespace std;

struct menuItemType
{
    string menuItem;
    double menuPrice;
};

void getData(int& listSize, menuItemType menuList[], int orderList[]);

int main()
{

    menuItemType *menuList = 0; //-----pointers
    int          *orderList = 0;
    int          listSize;

    getData(listSize, menuList, orderList);

    cout << menuList[0].menuItem;  //-----This is what crashes the program

    return 0;
}

//-----Get Menu Function
void getData(int& listSize, menuItemType menuList[], int orderList[])
{
    //-----Declare inFile
    ifstream inFile;
    string   price, size;

    //-----Open inFile
    inFile.open("Ch9_Ex5Data.txt");

    //-----Get Amount of Items, Convert to int
    getline(inFile, size);
    listSize = stoi(size);

    //-----Set Array Size
    menuList  = new menuItemType[listSize];
    orderList = new int[listSize];

    //-----Get Menu
    for (int x = 0; x < listSize; x++)
    {
        //-----Get menuItem
        getline(inFile, menuList[x].menuItem);

        //-----Get menuPrice convert to double
        getline(inFile, price);
        menuList[x].menuPrice = stod(price);
    }

    //------PRINT WORKS HERE ----- This print made me think i created the 
    //arrays correctly
    for (int x = 0; x < listSize; x++)
    {
        cout << menuList[x].menuItem << endl
            << menuList[x].menuPrice
            << endl;
    }

    inFile.close();
}

The contents of the .txt

8
Plain Egg
1.45
Bacon and Egg
2.45
Muffin
0.99
French Toast
1.99
Fruit Basket
2.49
Cereal
0.69
Coffee
0.50
Tea
0.75
1
  • Pass a pointer to the first element in the array as well as an integer that says what the size of the array is. pass(StructArray *sa, int sizeArray) Commented Apr 23, 2017 at 23:23

2 Answers 2

1

Setting menuList and orderList in getData does not update the pointers in main. It would if you used references to pointers:

void getData(int& listSize, menuItemType*& menuList, int*& orderList);

Even better, use references to std::vector and quit mucking around with owning pointers and new and delete.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! I've been stuck for longer than id like to admit.
1

Let's Rewrite your code for a better C++ness, with explanations. :)

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>

Don't do using namespace std just because you can type less things, namespaces helps you by telling you where this particular thing you invoked came from. if you really wanna write string instead of std::string, pull that particular thing, not the whole namespace, like this:

using std::string;

Your struct seems right, but you need to choose if your types will start with capitals or not, I always start my types with capitals but this is a choice:

struct MenuItemType
{
    string menuItem;
    double menuPrice;
};

Now, your getData should, well, get your data. so the type matters. your data is not 'void' as you declared, it's an array of MenuItemType, you can then declare them as vector and not even care about pointers.

Other thing: all of your parameters in getData shouldn't be parameters - they are all things that you would get from the text file that your program will parse, so the only thing that matters for the getData is the text file, so this is your variable.

std::vector<MenuItemType> getData(const std::string& textFile) 
{
    std::ifstream inFile;
    std::string   price, size, item;
    inFile.open(textFile);
    getline(inFile, size);
    int listSize = stoi(size);

    std::vector<MenuItemType> result;
    result.reserve(listSize);

    for (int x = 0; x < listSize; x++)
    {
        getline(inFile, item);
        getline(inFile, price);
        result.push_back(MenuItemType{item, stod(price)}); 
    }
    return result;
}

See how I didn't closed the file? It will be closed as soon as you leave the function, there's no need to call that unless you need the file to close before the function finishes.

Thumbs up rule: don't deal with pointers unless you have to.

As for your main function:

int main()
{
    std::vector<MenuItemType> menuList = getData("Ch9_Ex5Data.txt");
    cout << menuList[0].menuItem;
    return 0;
}

You could rewrite that in a faster way if you are sure what types are you using, the code above is equivalent to this one:

int main()
{
    auto menuList = getData("Ch9_Ex5Data.txt");
    cout << menuList[0].menuItem;
    return 0;
}

2 Comments

Great info! Thank you, I am currently a student, and we are going over structs, pointers, functions and so on. We havn't gotten to vectors yet. What you see in my code is about the extent of my knowledge. Comments like yours help me progress, Thanks!
You are welcome. one thing, the current way to teach modern c++ is to leave some advanced topics like pointers to later, when the student is better aquainted to the language.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.