dynamisches Array



  • Hallo,

    ich möchte in C ein Programm zur Verschlüsselung von Wörtern/kleinen Texten schreiben.

    Dabei möchte ich den zu verschlüsselnden Text von der Tastatur einlesen und in ein Char-Array speichern.

    Mein Problem ist nun folgendes:

    Ich möchte nicht zu Beginn ein Array mit fester Größe definieren, sondern ein dynamisches Array implementieren, das so groß wird, wie die Anzahl der eingelesenen Zeichen.

    Ist dies möglich und wenn ja wie?

    Schon mal Danke für Antworten



    • Du verwendest realloc
    • Du verwendest die GLib mit GArray
    • Du schreibst dir dein eigenes GArray


  • Hmm, an realloc hab ich auch schon gedacht. Aber dann muss ich ja vor der Eingabe festlegen, wie viele Buchstaben ich eingeben will, oder?



  • realloc ≠ malloc
    Du erstellst ein Array mit malloc (hier musst du die Anzahl Zeichen festlegen) und wenn das nicht ausreicht, vergrösserst du dieses mit realloc .

    Da ich das öfters brauche, habe ich mir entsprechende Funktionen/Makros dafür geschrieben (sofern ich nicht die GLib verwende).



  • Ich erstelle also ein Array mit malloc und lese dann mit fgets(?) ein.

    Wie verknüpfe ich denn die realloc-Funktion mit der fgets-Funktion, sodass mehr Speicher zur Verfügung steht, wenn mehr eingegeben wird, als durch malloc reserviert wurde?



  • celer schrieb:

    Ich erstelle also ein Array mit malloc und lese dann mit fgets(?) ein.

    Wie verknüpfe ich denn die realloc-Funktion mit der fgets-Funktion, sodass mehr Speicher zur Verfügung steht, wenn mehr eingegeben wird, als durch malloc reserviert wurde?

    Das geht so nicht. Du musst halt in diesem Fall mehrfach einlesen.



  • Ich hab so was noch hier rumliegen:

    char *get_line(FILE *stream) {
      size_t const CHUNKSIZE = 128;
    
      size_t n = 0;
      char *buf = NULL, *pos = NULL;
    
      if(feof(stream)) return NULL;
    
      do {
        char *p;
    
        n += CHUNKSIZE;
    
        p = realloc(buf, n + 1);
        if(p == NULL) {
          free(buf);
          return NULL;
        }
        buf = p;
        pos = buf + n - CHUNKSIZE;
    
        if(fgets(pos, CHUNKSIZE + 1, stream) == NULL) {
          if(feof(stream)) {
            return buf;
          } else {
            free(buf);
            return NULL;
          }
        }
      } while(pos[strlen(pos) - 1] != '\n');
    
      return buf;
    }
    

    Falls eine Bindung an GNU kein Problem darstellt, lege ich dir aber die getline-Funktion der glibc ans Herz - sie kann beim Einlesen mehrerer Zeilen den angeforderten Speicherbereich wieder und wieder verwenden, was deutlich effizienter sein kann.



  • Am besten ist, wenn du den dynamischen Speicher zur Aufnahme der Eingabe im aufrufenden Kontext verwaltest und damit die Eingabefunktion entlastest, z.B.

    int getline(char **s)
    {
      char in[2];
      int r=0;
      *s=realloc(*s,1);**s=0;
      while( fgets( in,2,stdin ) && *in!='\n' )
        strcat(*s=realloc(*s,++r+1),in);
      return r;
    }
    
    int main()
    {
      char *eingabe=0;
      if( getline(&eingabe) ) printf("\n1.Eingabe = %s",eingabe);
      if( getline(&eingabe) ) printf("\n2.Eingabe = %s",eingabe);
      ...
      realloc(eingabe,0);
      return 0;
    }
    


  • Mal abgesehen davon, dass

    *s = realloc(*s, foo);
    

    ein sehr gefährliches Unterfangen ist, willst du wirklich für jedes einzelne Zeichen wieder an den Heap gehen und das Ende des bisher eingelesenen Strings wieder neu bestimmen?

    Einen weniger performanten Weg, das Problem anzugehen, kann ich mir nur schwer vorstellen.


Log in to reply