Dynamische Größe von Arrays
-
Hallo zusammen,
ich sage direkt das ich totaler Neuling in C bin und daher noch so arge Probleme habe. Nun meine Fragestellung. Über die STDIN kriege ich verschiedene Zeilen geliefert die ich auslesen will:
A:2
B:3
C:ADWD
C:ADAFWF
C:WDAWD
D:200
D:100Diese will ich auslesen und mir in C dann merken. A ist die Anzahl der D-Werte und B die Anzahl der C-Werte.
So nun will ich einfach ein Array von chars bzw. shorts erstellen die die D-Werte bzw. C-Werte halten.
Ich denke ich habe da einen fehlen mit den Pointern oder so daher hier erstmal der Code:
#include <stdio.h> #include <stdlib.h> #include <string.h> char *substring(char *string, int position, int length) { char *pointer; int c; pointer = malloc(length+1); if (pointer == NULL) { printf("Unable to allocate memory.\n"); exit(EXIT_FAILURE); } for (c = 0 ; c < position -1 ; c++) string++; for (c = 0 ; c < length ; c++) { *(pointer+c) = *string; string++; } *(pointer+c) = '\0'; return pointer; } int main(int argc, char **argv){ char buf[BUFSIZ]; short a = 0; short b = 0; short anzc=0; short anzd=0; char *c; short *d; short i; while (fgets(buf, BUFSIZ, stdin) != NULL) { if (buf[strlen(buf)-1] == '\n') { char *isa = strstr(buf, "A:"); char *isb = strstr(buf, "B:"); char *isc = strstr(buf, "C:"); char *isd = strstr(buf, "D:"); if(isa){ char *sep = substring(isa,3,strlen(isa)); a = atoi(sep); d = malloc(a*sizeof(short)); }else if(isb){ char *sep = substring(isb,3,strlen(isb)); b = atoi(sep); c = malloc(b*sizeof(char)); }else if(isc){ char *sep = substring(isc,3,strlen(isc)); c[anzc] = sep; anzc++; }else if(isd){ char *sep = substring(isd,8,strlen(isd)); d[anzd] = sep; anzd++; } } } printf("%i\n", a); printf("%i\n", b); for(i=0; i<=anzc-1;i++){ printf("%c", c[i]); } return 0; }
Mit der While-Schleife lese ich von STDIN und dort möchte ich dann wenn ich B verarbeitet habe das Array anlegen um dann wenn C-Werte kommen diese darin zu speichern. Wo liegt da mein Fehler? In dem array c stehen nicht die Strings drin.
Grüße
-
spricht etwas dagegen, ohne malloc zu arbeiten?
-
ne eigentlich nicht hauptsache das array was ich anlege ich so groß nachdem ich a oder halt b gelesen habe
-
if (buf[strlen(buf)-1] == '\n')
diese bedingung dürfte extrem selten wahr werden.
der benutzer müsste exakt BUFSIZ-2 zeichen eingeben.
kann A:, B:, C:,jeweils nur einmal vorkommen?
wenns mehrmals vorkommt, dann versagt die if-struktur.
beschreib bitte in worten, was die funktion substring machen soll.
-
hola schrieb:
diese bedingung dürfte extrem selten wahr werden.
sorry, vergiss meinen kommentar, ich war auf nem falschen film.
aber die frage bleibt, wozu du auf '\n' abfragst.
-
hmm das funktioniert aber soweit echt prima. ich bekomme jede zeile in der if schleife und verarbeite die dann da.
naja substring ist schon sehr selbsterklärend: der string von einer bestimmten position bis zu einer position+länge des string
=> OK...dann auf deine neue Frage:
für nächste Zeile? hab den codesnipsel so gefunden. aber er funktioniert wirklich
-
c[anzc] = sep; d[anzd] = sep;
Hier kracht es, wenn für c, d kein Speicher allokiert wurde,
wenn z.B. die Angaben im String fehlerhaft sind oder so.
Poste doch mal ein oder zwei Beispiele, wie so eine Zeile aussehen kann.
-
Naja die Beispiele stehen ja oben:
C:AAAAA
C:BBBBB
C:CCCCC
D:1
D:199Habs noch mal vereinfacht und bisschen ins extreme getrieben. Naja es kracht halt einfach nicht. Wenn ich über die c mit der For-Schleife am Ende gehen kommt das raus:
@P`p?
-
-
bladepit schrieb:
Diese will ich auslesen und mir in C dann merken. A ist die Anzahl der D-Werte und B die Anzahl der C-Werte.
Ahaaa!
Du meinst also, dass der Wert hinter A: die Anzahl der Zeilen ist, die ein
am Anfang haben, entsprechendes mit B:?
Dann geht das so aber nicht. Du bräuchtest so etwas wie einen char** Zeiger.
Oder vllt. ne verkettete Liste.
Hast du dir die Aufgabe selbst ausgedacht? Wenn du das sowieso dynamisch machen willst, brauchst du A: und B: nicht.
-
Mir würde es viel mehr helfen wenn man sich dem Problem annimmt statt sowas. Ich weiß auch das das ne iF-Abfrage ist.
Ich entschuldige mich öffentlich für meinen schnellen verschreiber.
So ok knivil?
-
Das klingt schon ma nach ner Lösung CJosef. Ich brauch nur die Reihenfolge die per Ausgabe definiert wurde. Heißt C:AAAAA ist 0 C:BBBBB ist 1 etc.
Wie muss ich das denn realisieren?
-
Es gibt mehrere Möglichkeiten, das zu realisieren.
Wenn die maximale Anzahl der Zeilen feststeht und wenn die Anzahl nicht zu groß ist, tuts im einfachsten Fall eine Datenstruktur ala#define CZEILEN_MAX 100 #define DZEILEN_MAX 100 char czeilen[CZEILEN_MAX][BUFSIZ]; char dzeilen[DZEILEN_MAX][BUFSIZ];
Ansonsten müsstest du lernen wie man verkettete Listen programmiert oder wie man dynamische Listen per char** Zeiger realisiert, auch 2D Arrays genannt.
-
Ok womit ich dann noch ein Problem habe:
Kann ich diese Datenstrukturen dann erst erstellen wenn ich A und B gelesen habe?
Ich komme aus der Java-Welt da würde ich halt ein c = new char[b] machen...
-
Im Grunde brauchst du weder A noch B im Voraus zu kennen.
Bei verketteten Listen würdest du mit malloc Speicher reservieren, Zeilen kopieren, Zeilen anhängen oder an den Anfang setzen und bei der anderen Variante würdest du einen Index kontrollieren und könntest mit realloc arbeiten.
-
Was geht denn schneller? Es können schon sehr viele Werte für C und D sein. C bis zu 6 millionen...
-
realloc mit wachsendem Blockfaktor.
-
Hmm also:
tempc=realloc(c,(b)*sizeof(char)); /* give the pointer some memory */ if ( tempc != NULL ) { c=tempc; } else { free(c); }
Und dann add:
char *sep = substring(input,8,strlen(input)); c[anzc] = sep; anzc++;
Dann macht der folgende Output:
for(i=0; i<=anzc-1;i++){ printf("%c", c[i]); }
????? bei 5 Zeilen in der STDIN mit C.
Wo ist denn da der Fehler?
-
Am schnellsten läufts, wenn der (maximale)Speicherbedarf im Voraus bekannt ist(Anhahl Zeilen, maximale Anzahl der Zeichen pro Zeile) und der Speicher als zusammenhängender Speicherbereich vorliegt.
#define DZEILE_MAXLEN 256 unsigned anzahl_dzeilen = 4711; char (*dzeilen)[DZEILE_MAXLEN] = malloc ( anzahl_dzeilen * sizeof( *dzeilen ));
-
Jetzt verstehe ich gar nix mehr.
Resigniere...Thread kann geschlossen werden