传递动态数组结构c ++

时间:2017-04-23 23:16:38

标签: c++ arrays pointers parameter-passing dynamic-arrays

我需要读取.txt文件,并在名为getData的函数中使用第一个数字作为数组大小。

在我的代码中,我能够读取文件并将其指定为listSize的数组大小。我还可以使用.txt信息填充数组的其余部分。当我在getData函数中打印出我的数组中的内容时,它可以正常工作。

问题是,当我尝试访问getData函数之外的数组时,我的程序崩溃了。我是指针和c ++的新手。我不认为我正在传递它或正确地调用它。我很难找到信息来帮助解决问题。

如何访问我在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();
}

.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

2 个答案:

答案 0 :(得分:1)

menuList中设置orderListgetData不会更新main中的指针。如果你使用了对指针的引用:

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

更好的是,使用对std::vector的引用,并通过拥有指针和new以及delete来解决问题。

答案 1 :(得分:1)

让我们重写你的代码以获得更好的C ++,并附上解释。 :)

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

不要只使用命名空间std,因为你可以输入更少的东西,命名空间通过告诉你调用这个特定的东西来自哪里来帮助你。如果你真的想写字符串而不是std :: string,请拉出那个特定的东西,而不是整个命名空间,如下所示:

using std::string;

你的结构似乎是正确的,但你需要选择你的类型是否以大写字母开头,我总是用大写字母开始我的类型,但这是一个选择:

struct MenuItemType
{
    string menuItem;
    double menuPrice;
};

现在,你的getData应该得到你的数据。所以类型很重要。您声明的数据不是“无效”,它是一个MenuItemType数组,您可以将它们声明为向量,甚至不关心指针。

其他的事情:getData中的所有参数都不应该是参数 - 它们是你从程序将解析的文本文件中得到的所有内容,因此getData唯一重要的是文本文件,所以这是你的变量。

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;
}

看看我是怎么没关闭文件的?一旦你离开函数它就会被关闭,除非你需要在函数完成之前关闭文件,否则不需要调用它。

竖起大拇指规则:除非必须,否则不要处理指针。

至于你的主要功能:

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

如果你确定使用的是什么类型,你可以用更快的方式重写它,上面的代码等同于这个:

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