Arraylaenge an Daten anpassen
-
Hallo Zusammen!
Derzeit haenge ich an dem Problem die Groesse eines Arrays dynamisch anzupassen.
Hab mich auch schon ausgiebig mit malloc und realloc beschaeftigt, aber bisher leider noch keinen Erfolg erzielt.Das Problem liegt darin, dass ich eine Datei oeffnen will, z.B. Signal.dat.
Diese Datei wird immer eine Spalte haben, aber je nachdem mit wie vielen Samplen wir das Signal messen hat die Datei mal 1000, mal 2000 tausend Zeilen mit je einem Wert pro Zeile.
Ich hab erstmal einfach ein Array mit einem BUFFER von 1000 erstellt.
Jetzt wuerde ich gerne dieses Array dynamisch an die Zeilen der Datei anpassen.Ueber Tipps und Ratschlaege wuerde ich mich sehr freuen!
Vielen Dank,
Mark_W
-
Mark_W schrieb:
Hab mich auch schon ausgiebig mit malloc und realloc beschaeftigt, aber bisher leider noch keinen Erfolg erzielt.
Wenn du das wirklich gemacht hättest, würdest du diese Frage nicht stellen.
Die Antwort ist: realloc
Ein Array ist übrigens nicht mit realloc erweiterbar, weil die Größe nach der Definition nicht mehr änderbar ist. Du hast da falsche Vorstellungen über die Fachbegriffe.
-
Okay, ausgiebig mag vielleicht an dieser Stelle das falsche Wort sein, da hast du recht.
In meiner Vorstellung lese ich anfangs aus wie viele Zeilen die Datei Signal.dat hat und passe demnach meine Arraygroesse an.
Ist diese gleich 1000, ist alles prima, ist diese Groesser als 1000, so wuerde ich gerne mit realloc den Speicher dazu packen.
Leider komme ich nicht drauf wie ich das in C loese.
Bin mich seit zwei Wochen in C am reinarbeiten..
-
Poste doch mal bitte deinen bisherigen Code. Dann könnte man hier ansetzen.
-
Wenn du sowieso zuerst die Anzahl der Zeilen ermittelst, kannst du auch gleich explizit malloc verwenden, anstatt nochmal realloc zu bemühen.
-
Du weißt also schon vor der ersten Benutzung Deines Arrays, wieviel Speicher Du benötigst. Dann brauchst Du gar kein realloc, sondern ein Aufruf von malloc besorgt Dir den benötigten Speicher.
-
@Belli: Ja, ich weiss vorher zwar wie viele Zeilen meine Datei hat. Das aendert
sich auch waehrend der Programmausfuehrung nicht.Hier erstmal was Code von mir, bisher ohne malloc() und unvollstaendig.
Ich bin darueber hinaus auch nicht ganz glueklich mit dem auslesen der Zeilen, vll gibt es da eine andere Loesung fuer..#define BUFFER 999 /* Array Size Buffer */ int main() { FILE *fp; fp = fopen("Signal.dat","r"); if (fp == NULL) { printf("Error: can't open sample file!\n"); } /* Hier will ich nun die Anzahl der Zeilen bestimmen */ int i; int len++; while (i != EOF) { i = fgetc(fp); if (i == '\n') { len++; } } rewind(fp); if (len != BUFFER) { /* Mache mein Array um soviel Groesser wie fehlt */ } double Signal_Array[BUFFER];
-
So, ich hab jetzt noch ein bisschen rumprobiert und denke das sollte so funktionieren:
#include <stdio.h> #include <stdlib.h> int main() { FILE *fp; fp = fopen("Signal_Data.dat","r"); if (fp == NULL) { printf("Error: can't open sample file!\n"); } int i; int len = 0; while((i = fgetc(fp)) != EOF) { if (i == '\n') { len++; printf("%d\n",len); } } rewind(fp); double *A; A = malloc(sizeof(double)*(len+1)); if (NULL == A) { printf("No Memory!\n"); return EXIT_FAILURE; } int j; for(j = 0; j < len+1; j++) { double temp; fscanf(fp, "%lf\n", &temp); A[j] = temp; } fclose(fp); free(A); return 0; }
Passt das so mit dem aufruf von malloc() etc.?
-
#include <stdio.h> #include <stdlib.h> int main() { FILE *fp; fp = fopen("Signal_Data.dat", "r"); if (fp) { int blocksize = 1000, i = 0; double *a = malloc(blocksize*sizeof*a); while (1 == fscanf(fp, "%lf", &a[i])) { if (++i >= blocksize) a = realloc(a, (blocksize *= 2) * sizeof*a); } fclose(fp); while (i--) printf("%f\n", a[i]); free(a); } return 0; }
-
Danke Wutz.
Allerdings gibt das Programm meine Daten in umgedrehter Reihenfolge aus.
Das Erste Element steht an letzter Stelle usw..
-
Ist doch egal, wierum es ausgegeben wird?!
Wutz' Programm verdeutlicht, wie du mit
malloc
undrealloc
das Problem elegant lesen kannst. Ohne das Zählen von '\n' in der Datei.
-
Das stimmt und ich finde diese Moeglichkeit auch wesentlich besser.
Nur soll ja im weiteren Verlauf mit den Daten im Array gerechnet werden
und dafuer brauche ich die natuerlich in der richtigen Reihenfolge.
-
Die Daten sind in der "richtigen" Reihenfolge, nur die (Test)Ausgabe läuft rückwärts.
-
Okay, ich werde es mal versuchen einzubinden in mein Programm.
Koenntest du mir vielleicht noch kurz erklaeren wie folgender Teil des Pogramms
funktioniert:while (1 == fscanf(fp, "%lf", &a[i]))
Was ist 1?
-
Mark_W schrieb:
while (1 == fscanf(fp, "%lf", &a[i]))
Was ist 1?
Gegenfrage: was ist der Rückgabewert von
fscanf()
?
-
Ich denke mal die Anzahl der Argumente und das waere in diesem Fall 1.
Okay, das macht jetzt etwas mehr Sinn. Leider sagt mir das Programm wenn ich
aus der if-Bedingung rausgehe und Irgendwas mit dem Array anstellen will, dass das leer ist.. Irgendwas mache ich falsch..Ich versuche vll noch ein kleines Beispiel zu bringen.
-
Bis zum
fclose
steht in i die Anzahl der gelesenen Werte.
In derwhile
-Schleife danach wird i bis 0 runter gezählt.
-
Mark_W schrieb:
Ich denke mal die Anzahl der Argumente und das waere in diesem Fall 1.
Nein. Kein Foto für Dich.
Du wirst irgendwoher die Dokumentation der C-Standardbibliothek brauchen...
Ohne die kann man kaum von Dir verlangen, richtige Programme zu schreiben.Z.B. für
scanf()
hier http://en.cppreference.com/w/c/io/fscanf
-
Mark_W schrieb:
Ich denke mal die Anzahl der Argumente und das waere in diesem Fall 1.
Okay, das macht jetzt etwas mehr Sinn. Leider sagt mir das Programm wenn ich
aus der if-Bedingung rausgehe und Irgendwas mit dem Array anstellen will, dass das leer ist..Natürlich. Bei 'free' wird der Speicher ja auch wieder freigegeben (in Wutzs Code).
Der ist nämlich ein Beispiel, ein Muster. Jetzt wäre der richtige Zeitpunkt für ein bisschen Eigenleistung ...
-
Das ist mir schon klar, ganz kopflos handel ich hier auch nicht.
Ich habe mein komplettes Programm jetzt auch stehen mithilfe des Muster von
Wutz.Ich zeige hier noch schnell meine Abaenderungen und fuer mich ist dieser Thread
dann sehr erfolgreich gewesen. Ich danke euch allen fuer eure schnelle Hilfe!#include <stdio.h> #include <stdlib.h> int main() { FILE *fp; fp = fopen("Signal_Samples.txt", "r"); int blocksize = 1000, i = 0; double *a = malloc(blocksize*sizeof*a); if (fp) { while (1 == fscanf(fp, "%lf", &a[i])) { if (++i >= blocksize) a = realloc(a, (blocksize *= 2) * sizeof*a); } } int j; for (j = 0; j < i; j++) { printf("%d: %lf\n", j, a[j]); } fclose(fp); free(a); return 0; }