簡體   English   中英

傳遞結構的動態數組C ++

[英]Passing a dynamic array of structs c++

我需要讀取一個.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

getData中設置menuListorderList不會更新main的指針。 如果您使用了對指針的引用,它將:

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

更好的是,使用對std::vector引用,並通過擁有指針以及newdelete擺脫混亂。

讓我們通過解釋來重寫您的代碼,以獲得更好的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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM