2016-11-20 4 views
2

Ich versuche zu lernen, wie Speicher dynamisch für sehr lange Zeilen zugewiesen wird, wenn ich eine Datei lese. Ich suche hier und im Web und ich habe versucht, etwas Code.Eine Zeile aus einer Textdatei dynamisch lesen

Zum einen ist hier meine erste nicht-dynamischen Code:

char line[256]; 
file = fopen(inputFileName, "r"); 
// Here, of course I checked file is opened or not. 
while (fgets(line, sizeof(line), file)) { 
    // do some operations 
} 
// Closing operations 

Dies funktioniert für mich, wenn ich Dateien zu lesen. Aber hier muss die Zeile gleich oder kleiner als 255 Zeichen sein. Also, ich möchte zum Beispiel 300 Zeichen Länge Zeile aus der Datei lesen.

Ich habe versucht, Code folgende:

size_t maxl = 256; 
//char line[256]; 
char *line = malloc(maxl * sizeof(char)); 
if(!line){ 
    printf("Memory not allocated!!\n"); 
    return -2; 
} 
file = fopen(inputFileName, "r"); 

while (fgets(line, sizeof(line), file)) { 

    while(line[strlen(line) - 1] != '\n' || line[strlen(line) - 1] != '\r'){ 
     char *tmp = realloc (line, 2 * maxl); 
     //fgets(line, sizeof(line), file); 
     if (tmp) { 
      line = tmp; 
      maxl *= 2; 
     } 
     else{ 
      printf("Not enough memory for this line!!\n"); 
      return -3; 
     } 
    } 
    // do some operations 
} 

Ich habe versucht, Antworten auf diese Frage tatsächlich zu implementieren: Reading a line from file in C, dynamically

Aber es immer geben „Nicht genügend Speicher“ Teil des Codes. Also, was mache ich falsch?

Vielen Dank schon für Ihre Antworten und Hinweise.


Edit: Code aktualisiert ist abhängig von ersten Kommentaren.


Edit 2: Code wird immer gleich 3 Zeichen aus der Datei gelesen.

Stellen Sie sich vor, dass die Datei wie ist:

abcdabcdabcd... 

Die line Variable immer "abc" ist auch nach der erneuten Zuweisung Betrieb.

+1

Ihre while-Schleife wird nur beendet, wenn Sie neuen Text aus der darin enthaltenen Datei lesen, aber nicht. – Ryan

+0

Mögliches Duplikat von [Wie finde ich 'sizeof' (ein Zeiger, der auf ein Array zeigt)?] (Http://stackoverflow.com/questions/492384/how-to-find-the-sizeofa-pointer-pointing-to -an-array) –

+0

'sizeof (char *)' Falsch. Ordnen Sie ein Array von 'char *' zu? Nr. –

Antwort

1

Hier sind einige Korrekturen, die Sie tun müssen: (! Nur ein Vorschlag)

  • ändern char *tmp = realloc (line, 2 * maxl);-char *tmp = realloc (line, 2 * maxl * sizeof(char);.
  • Nach der Neuzuweisung des Speichers müssen Sie in der Datei suchen, um die vollständige Zeichenfolge zu lesen. Zum Beispiel wird fseek(file,0,SEEK_SET); auf den Anfang der Datei inputFileName suchen.
  • sizeof(line) wird immer ein Konstante Wert sein, da Sie die Größe eines Zeichenzeigers berechnen, nicht die Zeichenfolgenlänge. Ändern Sie also while (fgets(line, sizeof(line), file)) { zu while (fgets(line, maxl, file)) {.
  • Verschieben Sie die kommentierte Zeile //fgets(line, sizeof(line), file); in den Block if (tmp), da Sie die Zeichenfolge nach der Neuzuordnung erneut aus der Datei lesen möchten. Der Ausdruck line[strlen(line) - 1] != '\n' || line[strlen(line) - 1] != '\r' ist logisch falsch. Möglicherweise möchten Sie die Schleife nur dann eingeben, wenn das letzte Zeichen des line weder '\n' noch '\r' ist. Sie müssen also && anstelle von || verwenden.Hier

ist der modifizierte Code:

size_t maxl = 256; 
//char line[256]; 
char *line = malloc(maxl * sizeof(char)); 
if(!line){ 
    printf("Memory not allocated!!\n"); 
    return -2; 
} 
file = fopen(inputFileName, "r"); 

while (fgets(line, maxl, file)) { 

    while(line[strlen(line) - 1] != '\n' && line[strlen(line) - 1] != '\r'){ 
     char *tmp = realloc (line, 2 * maxl * sizeof(char)); 

     fseek(file,0,SEEK_SET);   //or wherever you want to seek to 
     if (tmp) { 
      line = tmp; 
      maxl *= 2; 
      fgets(line, maxl, file); 
     } 
     else{ 
      printf("Not enough memory for this line!!\n"); 
      return -3; 
     } 
    } 
    printf("%s\n",line);  //just to check 
} 

Die Probleme im Code waren:

  • Sie gelesen haben nur ein paar Zeichen aus der Datei, weil Sie sizeof(line) Anzahl der Zeichen gelesen haben nur und nicht maxl Anzahl der Zeichen.
  • Sie möchten möglicherweise einige Bytes zurücksuchen, um die gesamte Zeichenfolge erneut zu lesen, aber das liegt an Ihnen.
  • Erneutes Lesen einer Zeichenfolge aus der Datei nach Neuzuweisung nur, wenn die Neuzuweisung erfolgreich ist (if(tmp)).

Nun, warum Not enough memory.. wurde gedruckt?

Es war wegen der Schleife mehrere Male und die umverteilt Speichergröße (maxl Wert) ausgeführt wurde, wurde wie 256 zu erhöhen, 512, 1024, 2048, ..., 65536, ...

Wenn diese Größe wird groß genug, dass der Compiler die Neuzuweisung verweigert, wurde diese Fehlermeldung gedruckt. Wenn Sie möchten, versuchen Sie, Ihre Version des Codes zu debuggen oder den Wert maxl in jeder Iteration der inneren while Schleife zu drucken.

+1

Hey, skrtbhtngr. Danke für Ihre Erklärung, es ist sehr klar und informativ. Aber nachdem ich diese Zeilen korrigiert habe, bekomme ich wieder die Meldung "Nicht genug Speicher" – pilkington

+1

Ich habe den modifizierten Code ausprobiert, es funktioniert gut. Können Sie in jeder Iteration Ihren 'maxl' Wert überprüfen? – skrtbhtngr

+0

Beginnt von 256 und erhöht sich wie 512.1024, ... bis es keinen Speicher mehr gibt, wie Sie in Ihrer Antwort erwähnt haben – pilkington

Verwandte Themen