While Schleifen, Riesen Problem
-
Wie du es genau machen musst, hängt stark vom Aufbau deiner Datei ab. Du musst also erstmal festlegen, wie ein "Datensatz" in deiner Datei aussieht und damit eine struct deklarieren. Beim Einlesen der Datei füllst du dann die struct (pro Schleifendurchlauf also einen Datensatz). Wenn du alles eingelesen hast in den Arbeitsspeicher (struct-Arrays), dann kannst du dich um die Änderungen kümmern.
Wie man struct-Array anlegt, hab ich dir ja schon mit meinem Beispiel gezeigt. In diesem wird jede Zeile der Datei als "Datensatz" im struct-Array textzeilen gespeichert.
-
wie die datei aussehen soll, darüber brauche ich mir keine Gedanken machen, denn die Datei (test.txt) wird mir zur verfügung gestellt. und die sieht auf jeden Fall immer so aus:
<test> 455 producer gerd = "3456654" peter = "5586854" Heinz = "585854" <test> 123 tester lutz = "993" <test> 999 writer wilma = "3345" ... ... ...
was soll ich da nur für eine struktur schaffen? Jeweils die erste Zeile von einem solchen eintrag beginnt mit <test>, gefolgt von whitespaces, dann kommt die GrNummer, dann der Gruppenname. Alle Zeilen darunter haben die Form: whitespaces am anfang, dann der parameter (gerd bzw. Name), dann der wert (Bsp: "3456654").
... bis halt wieder eine Zeile mit test kommt.
ich habe mir ja überlegt, irgendwie den Datensatz anders aufzubauen. Und zwar, sobald <test> im string erscheint wird sich die gruppennummer und der gruppenname gemerkt. Anschließend wird in die nächste zeile gegangen, und dort an den namen (z.B. gerd) der gruppenname und die GrNummer angehängt werden und letztendlich 4 Datensätze in einer Zeile stehen.
Bsp.:455 producer gerd = "3456654" 455 producer peter = "5586854" 455 producer Heinz = "585854" 123 tester lutz = "993"
... und wenn ich dann so eine Form habe, dann lässt sich leichter ein struct bilden oder???
z.B.typedef struct { int GrNumber[MAXSPALTEN]; char GrName[MAXSPALTEN]; char name[MAXSPALTEN]; char number[MAXSPALTEN]; }zeile;
Könnte das so klappen? Weiß echt nicht wie ich das sonst anstellen sollte. Die Dateien sehen im Original exakt so aus, wie ich sie hier gepostet habe. Hoffe auf positive antworten.
-
Ruuuuudi schrieb:
ich habe mir ja überlegt, irgendwie den Datensatz anders aufzubauen. Und zwar, sobald <test> im string erscheint wird sich die gruppennummer und der gruppenname gemerkt. Anschließend wird in die nächste zeile gegangen, und dort an den namen (z.B. gerd) der gruppenname und die GrNummer angehängt werden und letztendlich 4 Datensätze in einer Zeile stehen.
Bsp.:455 producer gerd = "3456654" 455 producer peter = "5586854" 455 producer Heinz = "585854" 123 tester lutz = "993"
... und wenn ich dann so eine Form habe, dann lässt sich leichter ein struct bilden oder?
So kannst Du das schon machen, es kommt jetzt eher darauf an, für was die Daten später gebraucht werden (und wie das Format genau aussieht).
ZB könnte ich mir vorstellen, eine Art Map zu basteln, und die in der Datenstruktur zu hinterlegen.
-
habe es jetzt zumindest soweit, dass ich die test.txt auslese, alles wichtige entferne und in out.txt speichere. anschließend öffne ich die out.txt, lese diese zeilenweise ein und füge Gruppenname und-nummer mit hinzu, sprich ich habe jetzt pro durchlauf der whileschleife folgende Daten in variablen gespeichert:(überschriften sind die Variablennamen)
(GrNumber) (GrName) (Param) (Wert) 233 programmer gerd "3456654" 233 programmer peter "5586854" 442 tester ryu "85855"
so, diese werte habe ich also in jedem schleifendurchgang gespeichert. Wie kriege ich nun diese werte in ein struct? habe so begonnen:
typedef struct { char numb; char name; char par; char wert; } LINE; LINE l1 = {numb,name,par,wert};
so habe ich das struct vorbereitet.
Und wie kann ich das jetzt mit den gespeicherten werten füllen?
Kann mir jemand ein bsp. dafür geben, wie ich z.B.
die Zeile"233 programmer gerd "3456654""
in das struct einlese (an die bestimmten Stellen) und wie ich dann damit arbeiten kann.
-
Erstmal sorry, dass ich mich so lange nicht gemeldet hab :(.
Der Aufbau deiner Struktur ist schon mal ganz gut. Nur die Datentypen passen noch nicht ganz:
/* MAX_GRPNAME: Steht für die maximalen Zeichen für den Gruppennamen + Stringendezeichen Beispiel: Der Gruppenname darf maximal 20 Zeichen haben, dann sollte MAX_GRPNAME den Wert 21 haben. #define MAX_GRPNAME 21 MAX_USERNAME: Wie MAX_GRPNAME, aber für den Benutzernamen Beispiel: #define MAX_USERNAME 11 */ typedef struct { int grpnr; char grpname[MAX_GRPNAME]; char username[MAX_USERNAME]; long wert; } LINE;
Das Einlesen an sich geht recht einfach (fp_out_txt ist dein Stream zu out.txt):
fscanf(fp_out_txt, "%d %s %s %ld", &LINE.grpnr, LINE.grpname, LINE.username, &LINE.wert);
Das Schwierigste bei der ganzen Sache ist das dynamische Reservieren des Speicherplatz für dein struct-Array. Am besten wärs, wenn du vorher unabhängig von dieser Aufgabe dich etwas mit malloc() und realloc() auseinandersetzt und da auch erstmal mit einfachen Sachen. Versuch z. B. erstmal, dass der Benutzer eine beliebige Anzahl an Zahlen eingeben kann (z. B. in ein dynamisches int-Array) und dass am Ende dann die Zahlen in umgekehrter Reihenfolge ausgegeben werden und z. B. noch die Summe ausgegeben wird (aber nicht gleich jeden eingegebenen Wert summieren, sonst verfehlt es den Sinn der Sache ;)).
-
Thanx AJ,
hab mal noch ne kurze frage. Wie kann ich denn so ein struct in einer datei speichern?
fputs(LINE, file);
...das funzt nicht
-
Das kommt drauf an, wie diese Datei weiterverwendet werden soll.
Wenn du eine Textdatei brauchst (die Daten soll man sich also auch mit einem Texteditor ansehen können), dann solltest du das, in etwa so machen:
//Daten werden durch Komma getrennt als Text in die Datei geschrieben //Datei mit der Option "wt" o. ä. geöffnet (im Textmodus) fprintf(datei, "%d,%s,%s,%ld\n", LINE.grpnr, LINE.gprname, LINE.username, LINE.wert);
Eine andere Möglichkeit wäre diese (kann man sich nicht so einfach in einem Texteditor ansehen)
//Daten werden als Binärdaten abgespeichert //Datei mit der Option "wb" o. ä. geöffnet (im Binärmodus) fwrite(&LINE, sizeof(LINE), 1, datei);
Mit der letzten Variante könntest du sogar gleich das ganze struct-Array speichern:
LINE datensaetze[20]; //der Einfachheit halber mal ein statisches Array ... //hier werden die datensaetze gefüllt ... //Datensätze schreiben fwrite(datensaetze, sizeof(LINE), 20, datei); ...
-
so, soweit funzt es. Und wenn jetzt beide Structs gefüllt sind, wie kann ich diese noch vergleichen und notfalls umschreiben?
mein 1.struct sieht so aus:(überschriften sind spaltennamen)//test.txt GrNumber[10] GrName[80] Parameter[80] Wert[80] 112 Pros Karl 345 112 Pros Peter 1111-111 55 Tests Werni 232
... so sieht die erste struct aus.
die zweite struct sieht dann so aus:
//bat.txt GrNumber GrName Para Wer 001 heros knut 3456767 044 other kai 223 044 other kia 232 112 Pros --- --- 114 news gerd 444
... wie kann ich jetzt diese beiden structs vergleichen.
die bat.txt soll so lange durchgegangen werden, bis GrNumber und GrName (1.Eintrag aus test.txt) in bat.txt gefunden wurde. Wenn die gefunden wurden, dann sollen Parameter und wert ("---") in der bat.txt ersetzt werden... Aber wie?
(Bitte mit Beispiel...)
-
Das sollte eigentlich nicht das große Problem sein, oder??
Du musst deine 1. Struktur mit den Daten der test.txt einzeln durchgehen (also pro Datensatz) und dann bei jedem einzelnen Satz die 2. Struktur durchgehen, bis zu dem gewünschten Satz in der 2. Struktur. Also zwei verschachtelte Schleifen. Wenn du den Satz in der zweiten Struktur gefunden hast ersetzt du den Wert zum passenden Parameter mit dem Wert aus der ersten Struktur oder legst einen neuen Satz in der 2. Struktur an (wenn das gewünscht ist
).
Ist eigentlich nicht mehr als z. B. in einem String einen Teilstring zu suchen und diesen zu ersetzen bzw. in deinem Fall mehrere Teilstrings zu suchen und zu ersetzen ;).
-
kannst du mir dafür ein Codebeispiel geben?
-
Ok, weil du es bist ;):
typedef struct { int nr; char wert[20]; } record; ... record anders[2] = {{2, "zwei"}, {3, "drei"}}; int anzanders = 2; record daten[5] = {{1, "eins"}, {2, "two"}, {3, "three"}, {4, "vier"}, {5, "fünf"}}; int anzdaten = 5; int i, j; ... for(i = 0; i < anzanders; ++i) { for(j = 0; j < anzdaten; ++j) { if(anders[i].nr == daten[j].nr) { strcpy(anders[i].wert, daten[j].wert); } } } ...
Mehr ist nicht dabei. (In deinem Fall musst du die Bedingung hald noch etwas umstellen.)
-
danke, ist jetzt alles (eigentlich) klar... nur noch ne kurze frage: wie bekomme ich denn am besten die anzahl der datensätze des structs raus? Oder soll ich am besten gleich wenn ich das struct fülle einen zähler mitzählen lassen???
-
ruuuuudi schrieb:
Oder soll ich am besten gleich wenn ich das struct fülle einen zähler mitzählen lassen???
Ohne kommst du eh nicht aus, da du ohne einen Zähler der Funktion realloc() nicht den richtigen Wert übergeben kannst. Schließlich musst du den zu reservierenden Speicher aus der Anzahl der Datensätze mal dem Speicherbedarf der Struktur berechnen.