PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Kurze Frage[Dynamische Variablennamen]



homer56
09-01-2006, 10:21
Guten Tag

Mir ist grade etwas entfallen und ich komme einfach nicht mehr drauf, und die Suche bei google half nicht viel. Die Frage ist schnell beantwortet.


Ich möchte eine Variable erstellen welche sich aus 2 Teilen zusammensetzt.

Teil 1: sollte grp heissen
Teil 2: Hinter grp sollte eine dynamische Zahl folgen welche mit einer For-Schleife erhöht wird.

Also: grp1, grp2, grp3 etc.

Ich komm nur gerade nicht mehr drauf wie ich das mache, sorry für die dumme Frage und Danke schon im Vorraus.

BLUESCREEN3D
09-01-2006, 11:57
Meinst du Arrays?

Beispiel:

int grp[10];

Wenn wirklich der komplette Variablenname gemeint ist, dann kenne ich da nur den Präprozessor-Operator ##:

#define cat(a,b) a##b
cat(grp,1)=123; //ergibt grp1=123;
Das kannst du allerdings nicht dynamisch einsetzen, weil cat(grp,i) natürlich grpi und nicht grp1, grp2, usw. ergibt...

homer56
09-01-2006, 12:00
Edit: Moment mal hab gerade ein Chaos. Mit nem Array hab ich es gemacht, kann doch stimmen. Hmm hab da nen Denkfehler gemacht. Glaube es geht so, Danke.

Der Code-Abschnitt sieht wie folgt aus:


for(int g_count(0); g_count<group; g_count++){

GetInformation grpx //Bei x soll jedes mal die Zahl nach einem Durchgang erhöht werden, dazu sollte g_count verwendet werden
grp[g_count].getGroupInfos(g_count);

mainGrid->addWidget(grpx, g_count, 0); //hier nochmals das gleiche
}

xmarvel
09-01-2006, 18:50
du kannst die variablen namen nicht dynamisch zur Laufzeit erzeugen erstellen.
Du musst für dein Problem wie gesagt ein array benutzen.
Dein Code was du gepostet hast kann so nicht funktionieren.
Was hast du denn genau vor wieso brauchst du unterschiedliche Variablnenamen?

MfG
xmarvel

RHBaum
10-01-2006, 08:26
In C/C++ gibts keine "dynamischen Variablennamen" . Alle variablen werden vom compiler interpretiert mit nem symbolischen Namen (symbol) versehen. Das braucht er um beim linken der einzelnen obj. dateien die verweise auf die variablen korrekt aufzuloesen.

Natuerlich kannst du aber so eine funktionalitaet nachbilden, nur Deine variablenNamen duerfen dann nicht im Context von C/C++ laufen.

fuer ne normale numerierung wo per schleife durchlaeufst, bietet sich natuerlich nen array (vector villeicht fuer c++) an. unter C eh die einzige methode

Brauchst du den "dynamischen variablennamen" noch an andere stelle (besipielsweisse fuers serialisieren etc) dann bieten sich da maps als zuordnung zwischen string - wert an

Ciao ...

homer56
10-01-2006, 12:13
du kannst die variablen namen nicht dynamisch zur Laufzeit erzeugen erstellen.
Du musst für dein Problem wie gesagt ein array benutzen.
Dein Code was du gepostet hast kann so nicht funktionieren.
Was hast du denn genau vor wieso brauchst du unterschiedliche Variablnenamen?

MfG
xmarvel

Hi

Danke für die Info. Ich habe vor aus einer Datei herauszulesen wie viele Gruppen es gibt und für jede Gruppe ein Widget erstellt wird. In diese Gruppen Widget kommen dann die User. (Das Ganze wird aber nun mit QTreeView gemacht, muss mich nur noch einlesen).
Was geht den an diesem Code nicht?

@RHBaum

Danke auch dir für die Infos.


ps. Ist mein erstes grösseres Projekt wo ich dran bin, und auch gerade die ersten Gehversuche in QT.

Hab nochmals neu angefangen und versuche es gerade mit diesen Klassen zu lösen.


class GetUserInformation{

public:
int readUserAmount(void ); //Here we can get the information about the user amount to creat the treeview
string readUserNames(int uid); //Get the user names to creat the users in the treeview

void getUserAmount(void ); //Here we read the amount of the users form a file
void getUserName(void ); //Taking the usernames from a file and put into the string array

private:
int userAmount;
string userName[userAmount];
};


class GetGroupInformation{

public:
int readGroupAmount(void ); //Here we can get the information about the group amount to creat the treeview
string readGroupNames(int uid); //Get the group names to creat the users in the treeview

void getGroupAmount(void ); //Here we read the amount of the users form a file
void getGroupName(void ); //Taking the group names from a file and put into the string array

private:
int groupAmount;
string groupName[groupAmount];
};

Ist dies so brauchbar?

Joghurt
10-01-2006, 14:26
Äh... "readXXX" holt (engl. to get) die Daten aus der Klasse und "getXXX" liest (to read) die Daten ein?

Schlechtes API-Design, würde ich sagen ;)

homer56
10-01-2006, 14:44
Ok, ich schmeiss das Ganze in eine Klasse mach nen Konstruktor und je eine Methode für den Aufruf. Besser?

Joghurt
10-01-2006, 14:48
Es ging mir in erster Linie darum, das readXXX "gettet" und getXXX "readet"

RHBaum
11-01-2006, 12:21
gutes OO Design weare, wenn du zum Schluss nativen verstaendlichen code fuer eindeutige Operationen schreiben koenntest .....

also so in der Art :


UserInformation userInfo;

UserInformationFile file("userdata.dat");

if(file.parse(userInfo))
{
// weiterarbeiten
}
else
{
// irgend ne fehlerbehandlung anstossen
}



Wenn du das mit deinem Ansatz hinbekommst ... kein problem. Es gibt nicht immer "die beste Loesung" ...

string userName[userAmount];

du verwendest nen Array fester groesse (C-Array) auf strings ^^
Sicher das du da nen index brauchst ?
Sicher das die werte aneinander gereiht brauchst ?
Sicher das die anzahl der strings immer gleich ist ?

In C++ sollte man iteratoren verwenden an statt indizies ^^ wenn man kann.
damit kann man dann auch andere performantere container verwenden als vector / array

Ciao ...

homer56
11-01-2006, 12:39
du verwendest nen Array fester groesse (C-Array) auf strings ^^
Sicher das du da nen index brauchst ?
Sicher das die werte aneinander gereiht brauchst ?
Sicher das die anzahl der strings immer gleich ist ?


Wie bitte?
Ich möchte aus einer Datei alle User einlesen, besser Lösung bereit?
Wie meinst du das? Ich will ja die ganzen Namen und nicht nur den 1. Buchstaben.
Die wird ja definiert mit dem Konstruktor, also ist sie dynamisch würde ich sagen, oder liege ich falsch?

Sorry, sind meine ersten Versuch in diesem Bereich, bzw. hab bis jetzt nur mit kleinen Programme zu tun gehabt. Bin auch dankbar für weiterführende Links.

indizies, hab ich jetzt noch gar nie gehört. Oo

RHBaum
11-01-2006, 13:12
Ok, dann bestehen deine User nur aus einem String ? richtig ?

ja, wenn fuer den String den std::string benutzt, bist schon mal auf der richtigen seite ....

Aber fuer die "Haltung" deiner User benutzt nen statisches array .....

statische arrays benutzt man unter c++ eher seltener ....

da das halten von Werten gleichen types ne standard aktion in c/c++ ist, gibts unter c++ eben schon fertige "hilfsklassen" fuer.
da die STL ja schon verwendest, bieten sich die STL container an ....

auch in C gibt es mehrere moeglichkeiten, solche Datenpakete zu speichern .... und je nach anwendungsfall bietet sich da eine methode mehr oder weniger an .... hier mal die 2 wichtigsten

1. variante.
In einem Feld
Index (mehrzahl indizies) ist sozusagen die Position eines Elementes in dem Feld.
also array[1] -> ist das 2.Element im feld array ....
Diese Methode nimmt man, wenn man die Elemente am Steuck hintereinander braucht (zum befeueren plain c- funktionen aus anderen libs/dlls die keine klassen kennen z.b. oder wenn man komplette Datenbloecke schnell irgendwohin streamen will, oder wenn der index(also die Position) eine logische bedeutung hat )
In der STL iss der std::vector die klasse fuer dieses Einsatzgebiet

2. variante
Verkettete liste
es werden structuren(nodes) angelegt, die verweise auf das eigentliche element, sowie vorgaenger (und nachfolger bei doppelt verketteter liste) enthalten.
Damit kann man sich von element zu element hangeln.
Vorteile:
wenn man elemente unbekannter Anzahl verwalten will, muss man nicht auf verdacht Speicher allokieren, da die Elemente nicht zusammenhaengend im speicher liegen .... damit sind einfuege und loeschoperationen am anfang und ende besonders schnell
Nachteil:
Es gibt keinen Index, also keine Positionsangabe. Muss man notfalls selber mitzaehlen ....
Um zu bestimmten elementen zu kommen muss man "hangeln" ....

die doppelt verkettete Liste in der STL ist die std::list

Was genau du nun brauchst, musst du eben ueber deine Anforderungen ermittlen ....

Das mit dem Index hab ich gefragt wegen den Conatinern

Hat fuer dich die Position eines Users in dem "conatainer" wo es reinpacken willst, eine logische bedeutung ?

Also ist es wichtig, das "Mila" das 5. Element ist ?

wenn die nummern nur brauchst um auf elemente mittels schleife zuzugreifen
ist das keine logische Anforderung !

Also brauchst den Index dann nimm nen vector
brauchst ihn nicht, dann nim erstmal ne list ....

War das wenigstens bisserl verstaendlich ?

Caio ...

RHBaum
11-01-2006, 13:25
Links im internet kenn ich keine so guten, obwohls sicher paar gute tutorials gibt.

Ich hab mir die Buecher immer gekauft, da hat man was neben dem computer zum nachschlagen, und im bett was zum schneller einschlafen ^^

Wenn du wirklich intressiert bist, in C++ richtig einzusteigen, empfehle ich , un d die anderen sicher auch, zumindest paar standard werke in gedruckter form parat zu haben ...

"Die Programmiersprache C++" ist zum beispiel ein kandidat ...
oder "die Standard Type Library" ....

Ansonsten koennen die anderen dir sicher paar links im inet geben, wo man paar passende tutorials (frei von nicht standard erweiterungen wie beispielsweisse mfc, oder .net) bekommt.

Ciao ...

homer56
11-01-2006, 13:53
Oh vielen Dank! Ja hat mir geholfen. :-)

Die Position von den Usern ist im Moment nicht wichtig, bzw. hab mich noch für kein Sortierkrieterium festgelegt.

Was wichtig ist, ist das die Anzahl der User bekannst ist, da eine for-Schleife für jeden User einen List-Eintrag macht (QT-Basierender Listeintrag). Vor allem sobald ein User von einer Gruppe in die andere wandelt, muss die ganze Liste neu aufgebaut werden, dort ist der Aspekt welche Nummer wer hat auch unwichtig.


Buecher hab ich 3 Stück zu hause, zieh diese auch dem Virtuellen vor.
Nur fand ich dort nichts zu dem. ^^
Vorallem versuche ich das ganze Programm mit qt zu machen, wo es atm noch kein buch gibt von der Version 4 und das ganze verwirrt mich noch. ;-)

Vielen Dank nochmal :-)

RHBaum
12-01-2006, 16:01
Was wichtig ist, ist das die Anzahl der User bekannst ist, da eine for-Schleife für jeden User einen List-Eintrag macht (QT-Basierender Listeintrag). Vor allem sobald ein User von einer Gruppe in die andere wandelt, muss die ganze Liste neu aufgebaut werden, dort ist der Aspekt welche Nummer wer hat auch unwichtig.

Genau das ist eine standardanforderung an Container .... das man alle Elemente eines containers der reihe nach abhangeln kann. Das geht sowohl mit feldern als auch mit verketteten listen.

Diesen vorgang selber nennt man iterieren. Eine abstrakte Hilfsklasse dazu ist der Iterator.

Zum iterieren braucht man aber nicht zwangslaeufig die Anzahl, sondern die information, wenn die liste zu ende ist....
Nur bei arrays/Feldern verwendet man die anzahl um zu errechnen wo wirklich schluss ist ^^

Also fuer dich waer sowas eher nutzlich ^^


std::list<std::string> myList;

einfuegen ans ende geht einfach mit push_back ...

std::string strTest = "Test";
myList.push_back(strTest);

// nun das iterieren ... mittels einem iterator ....



for(std::list<std::string>::iterator it = myList.begin(); it != myList.end(); ++it)
{
// Iteratoren haben miestens den Dereferenzierungsop so ueberladen das dieser wie nen Zeiger auf das Element funktioniert !
std::string & strElement = *it; // achtung das ist nu eine referenz auf das Element in der Liste, keine Kopie ^^

}


Wichtig:
der Ende iterator, also list.end() ist nen gueltiges Iteratorelement, zeigt aber auf eine undefinierte stelle, well er hinter das letzte element zeigt (so kann man die Abbruchbedingungen besser definieren).
Wenn man den dereferenziert, gibts zoff ^^ Aber in normalen schleifen wie oben kommst nich in die gelegenheit ...

ciao ....