Dynamische Größe von Arrays
-
-
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
-
Deine substring Funktion kannst du rausschmeißen, deine Strings kannst du
mit den Standardfunktionen strcpy/strncpy in den allokierten Speicher kopieren.
Prinzipiel so in etwa:char* a = "A:25"; char* d = "D:100200300"; char* p; unsigned danzahl; p = strstr ( a, "A:"); if ( p != NULL ) { danzahl = atoi ( p + 2 ); // Ohne Validierung! printf ("anzahl d-zeilen: %u\n", danzahl ); } p = strstr ( d, "D:" ); if ( p != NULL ) puts ( p + 2 ); // Ab Position p + 2 kann mit strcpy bzw. mit strncpy gearbeitet werden.
-
Nochmal: das funktioniert alles. Können wir denn nicht über die Lösung meines Problems reden?
-
bladepit schrieb:
Jetzt verstehe ich gar nix mehr.
Wieso nicht. Es gibt nun mal mehrere Möglichkeiten.
bladepit schrieb:
Resigniere...Thread kann geschlossen werden
Schon?!
-
bladepit schrieb:
Nochmal: das funktioniert alles.
Der 'funktionierende' Code ist eine einzige memory-leak-factory.
bladepit schrieb:
Können wir denn nicht über die Lösung meines Problems reden?
Das ist das Ziel.
Ich wollte dir zeigen, wie man auf einfache Weise Code optimieren und unnötige Allokation vermeiden kann.
-
bladepit schrieb:
Nochmal: das funktioniert alles. Können wir denn nicht über die Lösung meines Problems reden?
Ja was denn nun?
Funktioniert alles, dann hast du kein Problem.int main(int argc, char **argv){ char buf[BUFSIZ]; short a = 0; short b = 0; short anzc=0; short anzd=0; char (*c)[BUFSIZ]; /* das hier war falsch, jetzt ist es korrekt ein Zeiger d.h. also quasi eine Liste auf String mit max. BUFSIZ-1 Länge */ short *d; short i; while (fgets(buf, BUFSIZ, stdin) != NULL) { if (buf[strlen(buf)-1] == '\n') { char *isa = strstr(buf, "A:")==buf; char *isb = strstr(buf, "B:")==buf; char *isc = strstr(buf, "C:")==buf; char *isd = strstr(buf, "D:")==buf; if(isa){ char *sep = buf+2; a = atoi(sep); d = malloc(a*sizeof(short)); }else if(isb){ char *sep = buf+2; b = atoi(sep); c = calloc(b,BUFSIZ); /* hier natürlich einen Speicherbereich definieren und anschließend als Stringliste gebrauchen! */ }else if(isc){ char *sep = buf+2; strcpy(c[anzc],sep); /* und hier natürlich keine einfache Zuweisung, sondern strcpy */ anzc++; }else if(isd){ char *sep = buf+2; d[anzd] = atoi(sep); anzd++; } } } printf("%i\n", anzc); printf("%i\n", anzd); for(i=0; i<anzc;i++){ printf("%s",c[i]); /* hier dann natürlich Strings ausgeben mit %s und nicht Zeichen %c wie du */ } return 0; }
-
Ok damit hast du mir geholfen. Ich bin immer für Optimierungen versteht mich da nicht falsch nur wollte ich das Programm erstmal zum laufen bringen.
Jetzt habe ich noch eine Frage. Wie muss ich ein Array anlegen und dann auch automatische vergrößern das folgende Eingaben beinhalten soll:
0 0 44
0 1 33
1 0 55
1 1 66Die ersten 2 Zahlen in jeder Reihe ist der Index. Die erste Spalte hat die Anzahl b und die zweite Spalte die Anzahl a.
Mir ist da nicht klar welche Typ das Array haben müsste und wie ich das dann entsprechend wenn ich die Größen von der STDIN gelesen habe auch vergrößere.
-
Ich habe nicht verstanden, was du erreichen willst und was diese Aufgabenstellung mit der vorigen gemeinsam hat.
-
Es kommen noch Werte ich halten muss. Zum einen brauch die alle Bezeichner das war quasi die vorherige Aufgabe und nun noch die Werte.
Dabei ist die dritte Spalte die Werte Spalte.