URL: https://www.overclockers.at/coding-stuff/c-help-array-of-structs_246178/page_1 - zur Vollversion wechseln!
Servus oc.at,
Komme bei einer Hausübung einfach nicht weiter.
Soll eine Datei binär eine .dat datei einlesen, in ein Struct speichern und dieses Struct, dann in eine Structtabelle, welche dynamisch erweitert wird.
Danach soll das ganze in eine XML datei geschrieben werden.
Mein Problem ist, dass ich zwar das Strukt einlesen kann und in das Strukt Array dann speichern kann, allerdings ist dann in dem Strukt Array in allen Positionen " [ ] " dasselbe drinnen
Code: C#pragma pack(push) #pragma pack(1) typedef struct { char Interpret[P]; char Album[P]; char Title[P]; int Tracknr; }structRec; #pragma pack(pop) structRec *Record; structRec **RecordTable; Record = calloc(size, sizeof(structRec)); RecordTable = calloc(size, sizeof(structRec)); // Input DAT if (!strcmp(ivalue,"dat")) { // Filestream Inputfile öffnen fpIN=fopen("mediaDB.dat", "rb"); printf("\nInput: mediaDB.dat\n"); } // Output XML if (!strcmp(ovalue,"xml")) { // Filestream Outputfile öffnen fpOUT=fopen("mediaDBout.xml", "w"); printf("\nOutput: mediaDBout.xml\n"); } k=0; // Lese Records aus Binärdatei while(fread(Record, sizeof(structRec), 1, fpIN) == 1) { if (!strcmp(ovalue, "xml")) { // Benötigter neuer Speicher size += sizeof(structRec); // Speicher reallozieren für Strukturtabelle RecordTable = (structRec*) realloc(RecordTable, size); // Speichere den eingelesenen Record in die Recordtabelle RecordTable[k] = Record; k++; } }

Wuerde mir fuer spaeteres traversieren immer merken, wie lange die Liste schon ist..
Code: Ctypedef struct { structRec **elem; size_t length; size_t capacity; } RecList;
Code: Csize_t newCapacity = recList->capacity+1; structRec ** newRecList = (structRec **) realloc(structRec->elem, newCapacity * sizeof(structRec); if (newRecList != NULL) { memset(newRecList + recList->capacity, 0, (newCapacity - recList->capacity) * sizeof(structRec); newRecList ->elem = newElementList; newRecList ->capacity = newCapacity; }
Irgendwas kann bei der Berechnung der Größe nicht stimmen.
Code: C// Benötigter neuer Speicher size += sizeof(structRec); // Speicher reallozieren für Strukturtabelle RecordTable = (structRec*) realloc(RecordTable, size*sizeof(structRec));
Das Problem ist, wie beim letzten Mal, dass du den Speicher, den du aus dem File einliest, nicht kopierst, sondern immer nur den Pointer kopierst.
Am Ende stehen in deiner Table lauter Pointer, die auf dem gleichen Speicher zeigen.
Du musst Record jedesmal neu allozieren, dann kannst du einfach wie bisher den Pointer kopieren.
Und RecordTable ist viel zu groß. Du brauchst nur um sizeof(Record*) zu erhöhen.
Das Programm liest ursprünglich ein xml file ein, macht ein csv draus, aus diesem dann ein dat und daraus wieder ein xml.
https://workupload.com/archive/crRGS2c
Hier die Dateien. Wurden von mir gekürzt, normalerweise sinds 13.000 records oder so. Jetzt schau ich mir mal eure Lösungsvorschläge an, danke!
@PuhBär: Ich versteh leider nur Bahnhof.
Was hat das jedesmal neu allozieren mit dem Pointer zu tun?
warum geht zb das nicht? Programm stürzt ab in dem Fall.
Code:strcpy(RecordTable[k]->Interpret, Record->Interpret);
Zitat von charminZitat von ccrIn Schottland kennst eh oft froh sein, wennst einmal 50km/h fahren kannst - und beim ständigen Ausweichen (weil die Straßen so eng sind) freust Dich auch über ein handlicheres Auto
Code: CstructRec *Record; structRec **RecordTable; Record = calloc(size, sizeof(structRec)); RecordTable = calloc(size, sizeof(structRec));
Code: C// Benötigter neuer Speicher size += sizeof(structRec); // Speicher reallozieren für Strukturtabelle RecordTable = (structRec*) realloc(RecordTable, size);
Code: C// Speichere den eingelesenen Record in die Recordtabelle RecordTable[k] = Record;
Zitat von thatP?
Zitat von thatWenn RecordTable eine Liste von Pointern ist, warum reservierst du dann sizeof(structRec) dafür?
Zitat von thatDu musst dich schon entscheiden, ob du eine Liste von Pointern auf structs oder eine Liste von structs speichern willst.
Zitat von thatDas kopiert nur einen Pointer, nicht den Inhalt von structRec. Wenn du eine struct kopieren willst, nimm memcpy.
ich würds so machen:
jedes struct bekommt einen eigenen pointer auf seinem dynamischen speicher und diese pointer werden in einer liste gespeichert. dann braucht man nie structs herumkopieren. in der einleseschleife muss natürlich jedes struct neu allociert werden und der pointer einfach in die liste geschrieben.
wie man die liste aufbaut ist im prinzip egal (ich gehe mal davon aus, dass die größe unbekannt ist), entweder als dynamisches array oder eine linked-list ist wohl am einfachsten. die listengröße am besten immer mitspeichern, ist für die nachfolgeoperationen komfortabler.
Okay, ich probiers mal weiter. Vielen Dank für euren Input. Wirklich! Ist nur grad etwas viel momentan mit Hackn, Schule, Projekt etc wah wah
Zitat von charminWeiss ich nicht, was ist "besser"?
):Code: Cstruct SomeRecord { char name[100]; ... }; // Deklaration: SomeRecord** array = NULL; size_t arraysize = 0; ... // Datensatz einfügen: ++arraysize; array = realloc(array, arraysize * sizeof(SomeRecord*)); // Platz für "arraysize" Pointer if (!array) handle_out_of_memory(); SomeRecord* currentRecord = calloc(1, sizeof(SomeRecord)); // Platz für einen Record reservieren array[arraysize - 1] = currentRecord; // den neuen Record im Array merken strlcpy(currentRecord->name, "test", sizeof(SomeRecord::name)); // irgendwas reinfüllen ... // alles freigeben: for (size_t i = 0; i < arraysize; ++i) free(array[i]); free(array);
okay, setz mich gleich dran!
danke 
overclockers.at v4.thecommunity
© all rights reserved by overclockers.at 2000-2026