2009-08-31 19 views
1

Je souhaite créer une structure à partir de données collectées par ligne à partir d'un fichier. Chaque ligne nécessite une nouvelle structure, et les lignes sont accédées dans une boucle while. En C# je l'ai fait en créant des structures anonymes et en les ajoutant à une liste de structures. C++ ne semble pas autoriser les structures anonymes. J'ai essayé de les nommer avec une variable incrémentée, mais cela n'a pas fonctionné, car le nom de variable a été pris littéralement - indépendamment, je préférerais ne pas être forcé d'utiliser cette méthode car je déteste l'idée de noms non pertinents. Je suppose que je pourrais nommer la structure par une propriété unique, mais, évidemment, je préfère utiliser une propriété comme. . . une propriété. D'ailleurs, que se passe-t-il s'ils ne sont pas tous nécessairement uniques? Est-ce que quelqu'un peut suggérer quelque chose ou expliquer quelque chose qui me manque?Création et collecte de structures C++ dans une boucle

Merci!

en C# (psuedo:

public static List<Referral> Referrals = new List<Referral>(); 

//in loop: 
var NewReferral = new Referral(referringURL.Trim(), referringWords.Trim().ToLower() , 1); 
if (NewReferral.URL == referringURL.Trim()) {Referrals.Add(NewReferral); 

en C++:

list<CollectedData> AllData; 

ifstream myFile("test_data.txt"); 
if (myFile.fail()) {cout << "Error opening file"; return 0;} 
else 
{ 
    cout << "File opened... \n"; 
    while(getline(myFile, line)) { 
    struct CollectedData; 
         //add property values 
         //add struct to struct list 
    } 
} 

(s'il vous plaît n'entrer dans les détails quand ils suppriment automatiquement, il ne sera probablement pas utile, mais je d aiment savoir.)

+1

Pouvez-vous poster du code (soit votre implémentation C# originale, soit votre tentative C++) afin que nous puissions avoir un aperçu de ce que vous essayez de faire? Ce n'est pas clair du tout pour moi. –

+0

Vous n'utilisez aucun type anonyme ici. – pingw33n

Répondre

9

C++ ressemble être sur la bonne voie, à part deux choses.Un, vous devez définir la forme de quelque part d'un CollectedData, et deux, vous devez donner un nom à votre variable struct:

Par exemple, si vous définissez l'CollectedData struct comme si

struct CollectedData { 
    int field1; 
    std::string field2; 
    bool field3; 
    // etc 
}; 

Ensuite, dans votre boucle interne vous pouvez le faire

while(getline(myFile, line)) { 
       CollectedData lineData; 
       //add property values 
       lineData.field1 = /*whatever*/; 
       lineData.field2 = /*whatever*/; 
       lineData.field3 = /*whatever*/; 
       //add struct to struct list 
       AllData.push_back(lineData); 
     } 

Chaque fois que dans la boucle un nouvel objet CollectedData est créé, et ses champs sont remplis, puis une copie de celui-ci est poussé dans la liste AllData, puis ailette L'objet est automatiquement détruit (rappelez-vous qu'une copie existe encore dans la liste).

Détail A propos Lorsque des objets sont détruits

C++ a trois sortes de stockage: statique, automatique et dynamique.

Des objets de stockage statique existent pour toute la durée de vie du programme. Tout objet créé en dehors d'une classe ou d'une fonction est statique (les globales sont statiques). Il en va de même pour tout ce qui est déclaré à l'intérieur d'une classe ou d'une fonction avec le mot-clé 'static'.

Les objets de stockage dynamique sont des objets créés avec le mot clé 'new' (ou avec malloc(), mais c'est un C-ism qui devrait généralement être évité en C++ sauf si c'est vraiment nécessaire). Les objets de stockage dynamique sont des objets dont la durée de vie est gérée manuellement par le programmeur. Un objet stocké dynamiquement continuera d'exister jusqu'à ce que vous le détruisiez avec le mot-clé "delete". Notez que le seulement vous pouvez accéder à un objet stocké dynamiquement via un pointeur ou une référence. Si vous n'utilisez pas de pointeur ou de référence, ce n'est pas dynamique (mais un pointeur/référence peut également faire référence à un objet non-dynamique). Les objets de stockage automatique sont vos variables régulières: les variables membres des structures et des classes, et les variables locales (y compris les paramètres) dans les méthodes et les fonctions.

Les objets de stockage automatique définis à l'intérieur des fonctions sont créés lorsque la ligne de code qui les définit est exécutée. Ils sont automatiquement détruits quand ils "sortent de la portée", c'est-à-dire, quand le bloc qu'ils ont déclaré à l'intérieur de se termine. En général, un "bloc" est un ensemble d'accolades: {}. Ainsi, tout ce qui est créé à l'intérieur d'une fonction est détruit quand la fonction retourne, et de même toute chose créée à l'intérieur du corps d'une boucle while est automatiquement détruite lorsque la boucle atteint sa fin (qu'elle soit terminée ou répétée).

Les objets de stockage automatique définis en tant que membres de classes ou de structures sont créés lorsque l'objet qui les contient en tant que membres est créé et détruit lorsque l'objet qui les contient en tant que membres est détruit.

(j'ai utilisé le terme « objet » à plusieurs reprises ci-dessus, mais les mêmes règles sont applicables aux types fondamentaux comme int, char, bool, etc.)

+0

+1 pour plus de clarté. La différence entre l'allocation dynamique et l'allocation de pile est également décrite ici: http://stackoverflow.com/questions/599308/proper-stack-and-heap-usage-in-c – Crashworks

0

Un struct en C++ est une structure de données, dont toute la "structure" (disposition, membres, types de membres) est définie au moment de la compilation. Voulez-vous peut-être quelque chose comme une table de hachage (ou une autre structure de données associative/semblable à une carte), où vous avez une de ces structures par ligne du fichier, par exemple un tableau?

1

Votre question est un peu floue sur ce que vous demandez. Je déduis que vous voulez dire que chaque structure a les mêmes champs pour chaque ligne, comme les colonnes d'une base de données SQL. Cela signifie que vous avez pas une définition de structure différente pour chaque ligne dans le fichier. Donc, en supposant que toutes vos structures ont les mêmes champs, le travail est facile; Il suffit de définir un constructeur de copie pour votre struct, et ensuite vous pouvez les ajouter à un std::vector ou un std::list ou votre propre implémentation de array/list/deque/whatever.

struct mystruct 
{ 
    int a,b,c; 
    // has default (shallow-copy) constructor, coz that's fine for integral types... 
} 

void readfromfile(YourFileClass *pFile, /* etc.. */) 
{ 
    mystruct temp; 
    std::list<mystruct> result; 
    // read each line into the temp struct one at a time, add to a list 
    while (pFile->ReadNextFileLineIntoStruct(&temp)) 
    { 
     result.push_back(temp); 
    } 
    // result has a linked list of data... 
} 

Vous pouvez également new une instance de votre struct chaque fois dans la boucle, et d'ajouter pointeurs à ces struct à la liste (comme Smashery suggère), mais sachez que ces objets ne seront pas libéré lorsque la liste est supprimée - vous devrez parcourir la liste entière et appelez delete sur chaque entrée lorsque vous avez terminé, ou vous ferez irrémédiablement de la mémoire.

(Vous pouvez aussi faire une classe qui hérite de std::list et libère correctement chaque entrée dans son destructor, mais cela entre dans un territoire dangereux si vous ne savez pas exactement ce que vous faites.)

0

Il n'y a pas une telle chose comme un type anonyme en C++. Vous devez définir explicitement la structure de ligne, puis vous devez définir la structure de données qui représente la collection de lignes.