Seite 1 von 1

Benötige Hilfe bei einer Funktion zum Einlesen einer Datei

Verfasst: So Dez 04, 2011 3:20 am
von 3VAD_YNCAL
Hallo liebe Community,

ich hätte da ein kleines Problemchen und würde mich über eure Hilfe
sehr freuen.

Ich versuche gerade eine Funktion zu schreiben, die eine Textdatei zum zeilenweisen Lesen öffnet und den Inhalt der Datei dann mittels strcat zeilenweise in einen zuvor reservertien Speicherbereich anhängt.
Ziel ist es dann, sich den Inhalt aus dem Speicherbereich über die Standardausgabe ausgeben zu lassen.

Doch leider bin ich bisher nicht wirklich erfolgreich mit diesem Versuch. Dummerweise komme ich auch nicht darauf, woran es letztendlich hakt.

Daher würde ich mich sehr über eure Hilfe freuen. Hier erstmal der Quellcode:

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ZEILE 255
#define BLOCK 10

enum { ERFOLG, FEHLER };

/*  ***vektor == zeigt auf einen Zeiger einer Zeile mit einem Zeiger auf die Länge der Zeile
 *  dateiname == Name der zu öffnenden Datei
 *  *zeile_n  == Zeiger auf Anzahl der Zeilen
 *  Rückgabewert: ERFOLG wenn kein Fehler, FEHLER wenn Fehler
 */

int datei_lesen(char ***vektor, char *dateiname, int *zeile_n)
{
    char puffer[ZEILE] = { 0 }; /* Puffer der zeilenweise einliest */
    char ***vektor_zeiger;       /* zum vergrößern des Speichers für vektor */
    char *zeiger;               /* zum vergrößern des Speichers für die Anzahl der Zeichen in einer Zeile */
    char *neuezeile = NULL;     /* Zeiger für neue Zeile */
    FILE *datei;                /* Datei zum Öffnen */

    int  fehler = ERFOLG;       /* Fehlerstatus */
    int  zeile = 0;             /* altuelle Zeile */
    int  alt_zeile_n;           /* Anzahl der Zeilen für die neuer Speicherplatz reserviert werden soll */
    int  absatz_n;

    *zeile_n = 0;

    if(BLOCK > 0 && ZEILE > 0)
    {                           /* Speicher für 10 Zeilen reservieren */
        vektor = malloc(BLOCK * sizeof(***vektor));

        if(NULL != vektor)
        {                       /* für jede Zeile jeweils Platz für 255 Bytes reservieren */
            for(zeile = 0; zeile < BLOCK; zeile++)
            {
                vektor[zeile] = malloc(ZEILE * sizeof(*vektor[zeile]));

                if(NULL == vektor[zeile])
                    fehler = FEHLER;

                else
                    vektor[zeile][0] = '\0';
            }
        }

        if(FEHLER == fehler)    /* Bei Fehler, Speicher wieder freigeben */
        {
            if(vektor != NULL)
            {
                for(zeile = 0; zeile < BLOCK; zeile++)
                {
                    if(vektor[zeile] != NULL)
                        free(vektor[zeile]);
                }
            }

            free(vektor);
            vektor = NULL;
        }
    }

    if(NULL != vektor)
    {
        datei = fopen(dateiname, "r");

        if(NULL != datei)
        {
            *zeile_n = BLOCK;
            absatz_n = 0;
            /* solange kein Fehler, zeilenweise einlesen */
            while(ERFOLG == fehler && NULL != fgets(puffer, ZEILE, datei))
            {
                neuezeile = strchr(puffer, '\n');
                /* Newline gegen Terminierungszeichen austauschen */
                if(NULL != neuezeile)
                    *neuezeile = '\0';

                strcat((*vektor)[zeile], puffer);

                if(NULL != neuezeile)
                {
                    absatz_n = 1;
                    zeile++;
                    /* Falls kein Platz mehr für Zeilen im Speicher, zusätzlich reservieren */
                    if(zeile >= *zeile_n)
                    {
                        alt_zeile_n = *zeile_n;
                        /* Bei negativem Wert, Zeilen entfernen */
                        if(BLOCK < 0)
                        {
                            for(zeile = alt_zeile_n-1; zeile >= alt_zeile_n + BLOCK; zeile--)
                                free((vektor)[zeile]);
                        }
                        /* Speicher für einzelne Zeilen reservieren */
                        vektor_zeiger = realloc(vektor, (alt_zeile_n + BLOCK)*sizeof(***vektor));

                        if(NULL != vektor_zeiger)
                        {
                            vektor = vektor_zeiger;

                            for(zeile = alt_zeile_n; zeile < alt_zeile_n + BLOCK; zeile++)
                            {   /* Speicher für Anzahl der Zeichen, die jede Zeile aufnehmen kann */
                                (*vektor)[zeile] = malloc(ZEILE);

                                if(NULL != (vektor)[zeile])
                                    (vektor)[zeile][0] = '\0';

                                else
                                    fehler = FEHLER;
                            }

                            *zeile_n += BLOCK;
                        }

                        else
                            fehler = FEHLER;
                    }
                }

                else
                {   /* Falls kein Newline, dann ist die Zeile länger als 255 Bytes */
                    absatz_n = 2;
                    /* Mehr Speicher für Anzahl der Zeichen in der Zeile reservieren */
                    zeiger = realloc(vektor[zeile], absatz_n * ZEILE);

                    if(zeiger != NULL)
                        vektor[zeile] = zeiger;

                    else
                        fehler = FEHLER;
                }
            }

            fclose(datei);
        }

        else
            fehler = FEHLER;    /* Falls Datei nicht geöffnet werden kann bzw. nicht existiert */
    }

    else
        fehler = FEHLER;    /* Falls Speicherallokation fehlschlägt */

    return(fehler);
}
Ich würde mich sehr über Hilfe von euch freuen. :)

Gruß
DAV3

Re: Benötige Hilfe bei einer Funktion zum Einlesen einer Dat

Verfasst: So Dez 04, 2011 11:03 am
von cloidnerux
Hi und Willkommen im Forum!
Ich versuche gerade eine Funktion zu schreiben, die eine Textdatei zum zeilenweisen Lesen öffnet und den Inhalt der Datei dann mittels strcat zeilenweise in einen zuvor reservertien Speicherbereich anhängt.
Ziel ist es dann, sich den Inhalt aus dem Speicherbereich über die Standardausgabe ausgeben zu lassen.
Klingt jetzt nicht so kompliziert, dein Code aber schon.
Du verwendest da viel malloc und wirfst viel mit Pointern herum.
Man könnte da sehr viel vereinfachen.
Gehe ich recht in der Annahme, das das eine Textdatei ist?
Doch leider bin ich bisher nicht wirklich erfolgreich mit diesem Versuch. Dummerweise komme ich auch nicht darauf, woran es letztendlich hakt.
Hilfreich zum Fehler finden, vor allem in so viel Code, ist eine exaktere Fehlerbeschreibung. Was soll Passieren und was passiert?

MfG cloidnerux

Re: Benötige Hilfe bei einer Funktion zum Einlesen einer Dat

Verfasst: So Dez 04, 2011 11:05 am
von Xin
Moin!

Ich habe mir das gerade mal auf den Rechner kopiert, um es zu kompilieren: Geht nicht: undefined reference to 'main'.
Bitte schreib ein Programm, was den Fehler provoziert, also eine main()-Funktion, damit man das Programm ausprobieren kann.

Schreib, was Du erwartest und was Du stattdessen erhältst.
Dass Du mit Deinem Versuch nicht erfolgreich bist, hilft bei der Suche nach dem Fehler nicht wirklich ;-D

FAQ: Wie formuliere ich eine Frage?

PS: Jetzt werden alle gleichzeitig wach ;-D

Re: Benötige Hilfe bei einer Funktion zum Einlesen einer Dat

Verfasst: Mo Dez 05, 2011 1:50 am
von 3VAD_YNCAL
Hallo zusammen,

tut mir Leid das ich so spät antworte, da ich ja diesen Thread erstellt habe und ich eigentlich von euch Hilfe brauche. :)
cloidnerux hat geschrieben:Gehe ich recht in der Annahme, das das eine Textdatei ist?
Ja. Ganz genau.

Ich werde euch jetzt versuchen mal ganz genau zu erkären, was ich eigentlich vor habe.
Das Hauptprogramm das ich versuche zu schreiben, soll nichts anderes tun als eine Textdatei zu öffnen und den Inhalt
der Datei mittels eines puffers erstmal zeilenweise einlesen. Die eingelesenen Zeilen sollen als String in einen zuvor mit malloc() reservierten Speicherbereich angehängt und von dort aus über stdout auf dem Bildschirm ausgegeben werden.

Ich möchte mit der Funktion

Code: Alles auswählen

int datei_lesen(char ***vektor, char *dateiname, int *zeile_n)
erst einmal Speicher für ***vektor mittels malloc() reservieren. Und genau daran scheitere ich gerade bei diesem Vorhaben!
(Ich bin noch ein ziemlicher Anfänger was die Programmierung angeht.)

Zunächst einmal der Funktionsaufruf in der main()-Funktion:

Code: Alles auswählen

int main()
{
     char **vektor = NULL;  // wird an die Funktion übergeben
     char datei[255];            // wird an die Funktion übergeben
     int  zeilen = 0;             // wird an die Funktion übergeben

...

/* Funktion soll dann folgendermaßen aufgerufen werden */
    if((datei_lesen(&vektor, datei, &zeilen) == FEHLER))
        printf("Fehler beim Lesen in Speicher!\n"), break;
... 
Wenn dann alles gut geht den Inhalt folgendermaßen ausgeben lassen:

Code: Alles auswählen

for(i = 0; i <= zeilen; i++)
    printf("%s\n", *vektor);
Das ganze möchte ich in einem Menü haben, in einer do_while_schleife. Auswahl [1] ist dann beispielsweise Datei komplett in den Speicher lesen (in diesem Fall die Funktion:
datei_lesen(char ***, *char, *int)).

DIe Funktion datei_lesen(char ***, *char, *int) soll folgendes tun:
------------------------------------------------------------------------------------
1.) Speicher reservieren für 10 Zeilen die je 255 Zeichen aufnehmen können
2.) Wenn Speicherallokation erfolgreich -> Datei zum Lesen öffnen
3.) Wenn Öffnen der Datei erfolgreich -> Inhalt d. geöffneten Datei zeilenweise einlesen
4.) Wenn der Inhalt der Datei mehr als 10 Zeilen benötigt, nochmals Speicher reservieren für weitere 10 Zeilen mit je 255 Zeichen (mittels realloc)
5.) Wenn eine eingelesene Zeile mehr als 255 Zeichen beinhaltet, soll der Speicher für diese Zeile vergrößert werden

Doch ich wäre eigentlich schon glücklich wenn erstmal Punkt 1 klappt. Denn genau da liegt für mich das eigentliche Problem. Ich habe keine Ahnung wie ich das innerhalb der Funktion realisieren soll.

Zum testen habe ich mal folgendes Programm geschrieben. Ich weiß nicht ob das syntaktisch ganz richtig ist, aber zumindest erfüllt es seinen Zweck:

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define  ZEILE  100
#define  BLOCK  10
#define  CLS    printf(" \033[2J");

enum { OK, NOT_OK };

int main()
{
    char **vektor = NULL;
    char puffer[ZEILE] = { 0 };
    char datei_name[50];
    char *neuezeile = NULL;
    FILE *datei;

    int  zeile;
    int  absatz_n;
    int  i;
    int  status = OK;

    CLS;

    printf("\bHallo User,\n\n");
    printf("nun wird erst einmal Speicher für eine Textdatei reserviert.\n"
           "-------------------------------------------------------------------------\n"
           "Achten sie bitte darauf, dass aber nur maximal Speicher für 10 Zeilen mit\n"
           "je 255 Zeichen reserviert werden kann!!!\n"
           "-------------------------------------------------------------------------\n"
           "Bitte drücken sie eine beliebige Taste\n"
           "-------------------------------------------------------------------------\n");
    getchar();

    vektor = malloc(BLOCK * sizeof(*vektor));

    if(NULL != vektor)
    {
        printf("Phase I der Speicherallokation war soweit erfolgreich!\n"
               "-------------------------------------------------------------------------\n");
        printf("\nDrücken sie bitte eine Taste für Phase II\n"
               "-------------------------------------------------------------------------\n");
        getchar();

        for(zeile = 0; zeile < BLOCK; zeile++)
        {
            vektor[zeile] = malloc(ZEILE * sizeof(*vektor)[zeile]);

            if(NULL == vektor[zeile])
            {
                printf("Phase II leider nicht erfolgreich!!!\n");
                printf("Bitte eine Taste drücken um den Speicher wieder vollständig freizugeben!\n");
                status = NOT_OK;
                getchar();
            }

            else
                vektor[zeile][0] = '\0';
        }

        if(NOT_OK == status)
        {
            if(vektor != NULL)
            {
                for(zeile = 0; zeile < BLOCK; zeile++)
                {
                    if(vektor[zeile] != NULL)
                        free(vektor[zeile]);
                }
            }

            free(vektor);
        }
    }

    if(NULL != vektor)
    {
        printf("OK!!!\n\n"
               "-------------------------------------------------------------------------\n");
        printf("Bitte geben sie die Datei mit Pfad an, die sie gerne öffnen möchten:\n"
               "-------------------------------------------------------------------------\n");
        scanf("%s", datei_name);

        datei = fopen(datei_name, "r");
        zeile = 0;

        if(NULL != datei)
        {
            while(fgets(puffer, ZEILE, datei) != NULL && zeile < BLOCK)
            {
                neuezeile = strchr(puffer, '\n');

                if(NULL != neuezeile)
                    neuezeile = '\0';

                strcat(vektor[zeile], puffer);

		zeile++;
            }

            printf("\nInhalt der Datei: %s\n", datei_name);
            printf("-------------------------------------------------------------------------\n");

            for(i = 0; i < zeile; i++)
                printf("%s", vektor[i]);

            printf("\n-------------------------------------------------------------------------\n");
        }

        else
            printf("\nDatei konnte nicht geöffnet werden, sorry!!!\n"
                   "-------------------------------------------------------------------------\n");
            return EXIT_FAILURE;
    }

    fclose(datei);
}
Hier klappt es soweit mit der Speicherallokation und dem Ausgeben des Inhalts auf dem Bildschirm.
Doch das nun als eigene Funktion zu schreiben? Klappt einfach nicht. Schon bereits bei der Speicherallokation kommt Segmentation fault. Siehe Beispiel in meinem ersten Post.
Ich habe so viele Fragen doch dies würde den Sinn und Zweck dieses Threads deutlich sprengen. Trotzdem würde ich gerne zumindest eine dieser vielen Fragen hier stellen.

Beispiel mit char **vektor:

Code: Alles auswählen

char **vektor = NULL;
vektor = malloc(BLOCK * sizeof(*vektor));
if(NULL != vektor)
{
    for(zeile = 0; zeile < BLOCK; zeile++)
    {
        vektor[zeile] = malloc(ZEILE * sizeof(*vektor)[zeile]);
        if(NULL == vektor[zeile])
            printf("Fehler bei malloc()!\n");
        else
            vektor[zeile][0] = '\0';
Wenn das syntaktisch richtig ist, wie realisiere ich das mit char ***vektor???

Sorry für diesen ewig großen Post. Doch nun hoffe ich, ihr versteht nun mein Problem und könnt mir dabei helfen es zu lösen. Wenn ihr wollt, natürlich. :)

Gruß
DAV3

Re: Benötige Hilfe bei einer Funktion zum Einlesen einer Dat

Verfasst: Mo Dez 05, 2011 7:20 am
von cloidnerux
Ja. Ganz genau.
Dann wird das ganze wesentlich einfacher.
Ich werde euch jetzt versuchen mal ganz genau zu erkären, was ich eigentlich vor habe.
Das Hauptprogramm das ich versuche zu schreiben, soll nichts anderes tun als eine Textdatei zu öffnen und den Inhalt
der Datei mittels eines puffers erstmal zeilenweise einlesen. Die eingelesenen Zeilen sollen als String in einen zuvor mit malloc() reservierten Speicherbereich angehängt und von dort aus über stdout auf dem Bildschirm ausgegeben werden.
Schau dir mal fseek() an, damit kannst du die GESAMTGRÖßE der Datei bestimmen und musst da nicht so ein Provisorium machen, damit reduziert sich der Code und du kannst dir sicher sein, das du genug speicher hast.

Dann: Wieso Zeilenweise? Eine Zeile in einem Textdokument wird mit einem \n beendet, des bedeutet, wenn du alles auf einmal einliest, hast du auch die Zeilenumbrüche schon mit gelesen.

Code: Alles auswählen

vektor = malloc(BLOCK * sizeof(*vektor));
Das kann auch nicht Funktionieren, weil vektor ist ein Zeiger AUF einen ZEIGER. Mit deiner Zuweisung, weist du vektor ein neuen Speicher zu, in dem du ZEIGER erwartest, und nicht Daten.
Es müsste

Code: Alles auswählen

*vektor = malloc(BLOCK * sizeof(**vektor));
heißen, wenn überhaupt.
Wieso willst du egt einen Zeiger auf einen Zeiger übergeben?
Wenn das syntaktisch richtig ist, wie realisiere ich das mit char ***vektor???
Nein, das gibt es nicht.

Ich habe gerade leider nicht mehr Zeit, daher kann ich nicht auf alles eingehen, daher hoffe ich, da sich dir damit schon helfen konnte.

MfG cloidnerux.

Re: Benötige Hilfe bei einer Funktion zum Einlesen einer Dat

Verfasst: Mo Dez 05, 2011 2:43 pm
von 3VAD_YNCAL
cloidnerux hat geschrieben:

Code: Alles auswählen

vektor = malloc(BLOCK * sizeof(*vektor));
Das kann auch nicht Funktionieren, weil vektor ist ein Zeiger AUF einen ZEIGER. Mit deiner Zuweisung, weist du vektor ein neuen Speicher zu, in dem du ZEIGER erwartest, und nicht Daten.
Es müsste

Code: Alles auswählen

*vektor = malloc(BLOCK * sizeof(**vektor));
heißen, wenn überhaupt.
Dann habe ich ja überhaupt nichts verstanden. Habe ich doch nun ein Jahr C gelernt und verstehe nur Bahnhof :(Dieses Programm das ich geschrieben habe:

Code: Alles auswählen

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #define  ZEILE  100
    #define  BLOCK  10
    #define  CLS    printf(" \033[2J");

    enum { OK, NOT_OK };

    int main()
    {
        char **vektor = NULL;
        char puffer[ZEILE] = { 0 };
        char datei_name[50];
        char *neuezeile = NULL;
        FILE *datei;

        int  zeile;
        int  absatz_n;
        int  i;
        int  status = OK;

        CLS;

        printf("\bHallo User,\n\n");
        printf("nun wird erst einmal Speicher für eine Textdatei reserviert.\n"
               "-------------------------------------------------------------------------\n"
               "Achten sie bitte darauf, dass aber nur maximal Speicher für 10 Zeilen mit\n"
               "je 255 Zeichen reserviert werden kann!!!\n"
               "-------------------------------------------------------------------------\n"
               "Bitte drücken sie eine beliebige Taste\n"
               "-------------------------------------------------------------------------\n");
        getchar();

        vektor = malloc(BLOCK * sizeof(*vektor));

        if(NULL != vektor)
        {
            printf("Phase I der Speicherallokation war soweit erfolgreich!\n"
                   "-------------------------------------------------------------------------\n");
            printf("\nDrücken sie bitte eine Taste für Phase II\n"
                   "-------------------------------------------------------------------------\n");
            getchar();

            for(zeile = 0; zeile < BLOCK; zeile++)
            {
                vektor[zeile] = malloc(ZEILE * sizeof(*vektor)[zeile]);

                if(NULL == vektor[zeile])
                {
                    printf("Phase II leider nicht erfolgreich!!!\n");
                    printf("Bitte eine Taste drücken um den Speicher wieder vollständig freizugeben!\n");
                    status = NOT_OK;
                    getchar();
                }

                else
                    vektor[zeile][0] = '\0';
            }

            if(NOT_OK == status)
            {
                if(vektor != NULL)
                {
                    for(zeile = 0; zeile < BLOCK; zeile++)
                    {
                        if(vektor[zeile] != NULL)
                            free(vektor[zeile]);
                    }
                }

                free(vektor);
            }
        }

        if(NULL != vektor)
        {
            printf("OK!!!\n\n"
                   "-------------------------------------------------------------------------\n");
            printf("Bitte geben sie die Datei mit Pfad an, die sie gerne öffnen möchten:\n"
                   "-------------------------------------------------------------------------\n");
            scanf("%s", datei_name);

            datei = fopen(datei_name, "r");
            zeile = 0;

            if(NULL != datei)
            {
                while(fgets(puffer, ZEILE, datei) != NULL && zeile < BLOCK)
                {
                    neuezeile = strchr(puffer, '\n');

                    if(NULL != neuezeile)
                        neuezeile = '\0';

                    strcat(vektor[zeile], puffer);

          zeile++;
                }

                printf("\nInhalt der Datei: %s\n", datei_name);
                printf("-------------------------------------------------------------------------\n");

                for(i = 0; i < zeile; i++)
                    printf("%s", vektor[i]);

                printf("\n-------------------------------------------------------------------------\n");
            }

            else
                printf("\nDatei konnte nicht geöffnet werden, sorry!!!\n"
                       "-------------------------------------------------------------------------\n");
                return EXIT_FAILURE;
        }

        fclose(datei);
    }
tut genau das was es soll. Und das mit

Code: Alles auswählen

char **vektor = NULL;
vektor = malloc(BLOCK * sizeof(*vektor));
Mit

Code: Alles auswählen

*vektor = malloc(BLOCK * sizeof(**vektor));
...natürlich die restlichen Zeilen ebenfalls angepasst, bekomme ich dann nur Segmentation fault.
Aber warum? Könntest du mir anhand des o.g. Quellcodes zeigen, wie es mit

Code: Alles auswählen

*vektor = malloc(BLOCK * sizeof(**vektor));
funktioniert? Einfach nur da mit ich mir ein Bild machen kann.
Ich habe C überwiegend anhand von Jürgen Wolf's C von A bis Z gelernt. Aber langsam glaube ich den anderen wenn die sagen, dass man da lieber andere Lektüren nehmen soll.
Bitte würde mich freuen, wenn du mir diesen Gefallen tun könntest.

Gruß
3VAD_YNCAL

Re: Benötige Hilfe bei einer Funktion zum Einlesen einer Dat

Verfasst: Mo Dez 05, 2011 2:53 pm
von cloidnerux
Ich habe C überwiegend anhand von Jürgen Wolf's C von A bis Z gelernt. Aber langsam glaube ich den anderen wenn die sagen, dass man da lieber andere Lektüren nehmen soll.
Zeiger sind schwierig, aber nicht unmöglich zu verstehen, man muss nur anfangen sich das Bildlich vorzustellen:
Ein Zeiger ist immer ein Pfeil, der auf irgendwas zeigt, selbst wenn es nur ein anderer Zeiger ist.
Nun musst du dich fragen, was will ich erreichen, bzw was will ich wissen?
Den aus Zeigern kannst du 3 Informationen bekommen:
Wo ist der Zeiger an sich im Ram(&pointer)
Wohin zeigt der Zeiger(pointer) und was sind die Daten am ende des Zeigers(*pointer).
Und nun kommen wir zu deiner Situation:
Du hast einen Zeiger auf einen Zeiger, bzw auf mehrere Zeiger, welche dann auf die einzelnen Zeichen Zeigen, wie ich hier in dem Bild Illustriere:
pointer-png.png
Und das Bereitet dir Probleme, den du musst 2 mal Speicher reservieren für 2 Verschiedene Dinge, einmal brauchst du Platz für deine Zeiger und dann nochmal Platz für die texte auf die die Zeiger des Vektors zeigen.
Und das bereitet dir Probleme.
Ich hoffe ich konnte dir das Problem Illustrieren und dir etwas helfen.

MfG cloidnerux.

Re: Benötige Hilfe bei einer Funktion zum Einlesen einer Dat

Verfasst: Mo Dez 05, 2011 11:49 pm
von 3VAD_YNCAL
So - habe es nun endlich geschafft. Natürlich ist es bestimmt noch deutlich verbesserungswürdig, aber zumindest funktioniert es erst einmal.

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ZEILE 255
#define BLOCK 10

enum { ERFOLG, FEHLER };

int datei_lesen(char ***vektor, char *dateiname, int *zeile_n)
{
    char puffer[ZEILE] = { 0 };
    char ***vektor2;
    char **vektor_zeiger;
    char *neuezeile = NULL;
    FILE *datei;

    int  fehler = ERFOLG;
    int  zeile = 0;
    int  alt_zeile_n;

    *zeile_n = 0;

    if(BLOCK > 0 && ZEILE > 0)
    {
        vektor_zeiger = malloc(BLOCK * sizeof(*vektor_zeiger));

        if(NULL != vektor_zeiger)
        {
            for(zeile = 0; zeile < BLOCK; zeile++)
            {
                vektor_zeiger[zeile] = malloc(ZEILE * sizeof(*vektor_zeiger[zeile]));

                if(NULL == vektor_zeiger[zeile])
                    fehler = FEHLER;

                else
                    vektor_zeiger[zeile][0] = '\0';
            }
        }

        if(FEHLER == fehler)
        {
            if(vektor_zeiger != NULL)
            {
                for(zeile = 0; zeile < BLOCK; zeile++)
                {
                    if(vektor_zeiger[zeile] != NULL)
                        free(vektor_zeiger[zeile]);
                }
            }

            free(vektor_zeiger);
            vektor_zeiger = NULL;
        }
    }

    *vektor = vektor_zeiger;

    if(NULL != *vektor)
    {
        datei = fopen(dateiname, "r");

        if(NULL != datei)
        {
            *zeile_n = BLOCK;
            zeile = 0;

            while(ERFOLG == fehler && NULL != fgets(puffer, ZEILE, datei))
            {
                neuezeile = strchr(puffer, '\n');

                if(NULL != neuezeile)
                    *neuezeile = '\0';

                strcat((*vektor)[zeile], puffer);

                if(NULL != neuezeile)
                {
                    zeile++;

                    if(zeile >= *zeile_n)
                    {
                        vektor2 = vektor;
                        alt_zeile_n = *zeile_n;

                        vektor_zeiger = realloc(*vektor2, (alt_zeile_n + BLOCK) * sizeof(**vektor2));

                        if(NULL != vektor_zeiger)
                        {
                            *vektor2 = vektor_zeiger;

                            for(zeile = alt_zeile_n; zeile <= (alt_zeile_n) + BLOCK; zeile++)
                            {
                                (*vektor2)[zeile] = malloc(ZEILE);

                                if(NULL != (*vektor2)[zeile])
                                    (*vektor2)[zeile][0] = '\0';

                                else
                                    fehler = FEHLER;
                            }

                            vektor = vektor2;
                            zeile -= 10;
                            *zeile_n += BLOCK;
                        }

                        else
                            fehler = FEHLER;
                    }
                }
            }

            fclose(datei);
        }

        else
            fehler = FEHLER;
    }

    else
        fehler = FEHLER;

    return(fehler);
} 
Dankeschön an euch allen.
Gruß DAV3