2017-04-23 1 views
1

Je dois lire un fichier .txt et utiliser le premier nombre comme taille de tableau dans une fonction appelée getData.Passer un tableau dynamique de structures C++

Dans mon code, je suis capable de lire le fichier et l'affecter à la taille du tableau listSize. Je suis également capable de remplir le reste du tableau avec les informations .txt. Lorsque j'imprime ce qui est dans mon tableau dans la fonction getData, cela fonctionne.

Le problème est que lorsque j'essaie d'accéder à la matrice en dehors de la fonction getData, mon programme se bloque. Je suis nouveau pour les pointeurs, et C++ en général. Je ne pense pas que je le passe ou l'appelle correctement. J'ai eu du mal à trouver des informations pour m'aider dans le problème.

Comment puis-je accéder aux tableaux que j'ai créés au 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(); 
} 

Le contenu du .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 
+0

Passez un pointeur sur le premier élément du tableau ainsi qu'un entier indiquant la taille du tableau. 'passe (StructArray * sa, int tailleArray)' –

Répondre

1

Réglage menuList et orderList dans getData ne met pas à jour les pointeurs dans main. Il serait si vous avez utilisé des références à des pointeurs:

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

Mieux encore, utiliser des références à std::vector et quit bidouillent possédant des pointeurs et new et delete.

+0

Merci! J'ai été bloqué plus longtemps qu'id à l'admettre. –

1

Réécrivons votre code pour un meilleur C++, avec des explications. :)

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

Ne pas faire à l'aide namespace std juste parce que vous pouvez taper moins de choses, vous aide namespaces par vous dire où cette chose particulière que vous invoquez est venu. si vous voulez vraiment la chaîne d'écriture au lieu de std :: string, tirez cette chose particulière, pas l'espace de noms tout, comme ceci:

using std::string; 

Votre struct semble juste, mais vous devez choisir si vos types vont commencer avec les capitales ou non, je commence toujours mes types de chapiteaux mais c'est un choix:

struct MenuItemType 
{ 
    string menuItem; 
    double menuPrice; 
}; 

maintenant, votre getData devrait, bien, récupérer vos données. donc le type compte. vos données ne sont pas 'nules' comme vous l'avez déclaré, c'est un tableau de MenuItemType, vous pouvez ensuite les déclarer comme vecteur et ne pas même se soucier des pointeurs.

Autre chose: tous vos paramètres dans getData ne doivent pas être des paramètres - ils sont tout ce que vous obtiendriez du fichier texte que votre programme analysera, donc la seule chose qui compte pour le getData est le fichier texte , donc c'est votre 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; 
} 

Voir comment je n'ai pas fermé le fichier? Il sera fermé dès que vous quittez la fonction, il n'est pas nécessaire de l'appeler à moins que vous ayez besoin de fermer le fichier avant la fin de la fonction. Règle du pouce levé: ne traitez pas les pointeurs à moins d'y être obligé.

En ce qui concerne votre fonction principale:

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

Vous pouvez réécrire que dans une façon plus rapide si vous êtes sûr quels types utilisez-vous, le code ci-dessus est équivalent à celui-ci:

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

Bonne info! Merci, je suis actuellement un étudiant, et nous allons sur les structures, les pointeurs, les fonctions et ainsi de suite. Nous ne sommes pas encore arrivés à des vecteurs. Ce que vous voyez dans mon code concerne l'étendue de mes connaissances. Des commentaires comme le vôtre m'aident à progresser, merci! –

+0

Vous êtes les bienvenus. une chose, la façon actuelle d'enseigner le C++ moderne est de laisser certains sujets avancés comme des pointeurs plus tard, quand l'étudiant est mieux familiarisé avec la langue. –