2016-03-23 6 views
0

Ich habe ein Stück Code geschrieben, die eine Textdatei foo.txt liest, die von Format ist:Kann jemand den Segmentierungsfehler in diesem erklären?

1 
2 
3 
4 

Es speichert die zuletzt gewählte Nummer und erhöht sie und schreibt sie zurück. Dies ist der Teil, wo ich die letzte Nummer speichern und der nächste Teil des Codes wird die Nummer in die Datei schreiben. Die Datei wird von ./readfile 100 foo.txt aufgerufen, wobei 100 die Anzahl angibt, mit der die letzte Nummer erhöht werden muss.

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

int main(int argc, char *argv[]) { 
    FILE *fp; 
    char ch[100]; 
    int i = 0; 
    int j = 0; 
    int count = atoi(argv[1]); 

    while (count != 0) { 
     fp = fopen(argv[2], "r"); 
     while (fp) { 
      ch[i] = fgetc(fp); 
      i++; 
      j = i; 
      printf("%d", j);  
     } 
     fclose(fp); 
     count--; 
    } 
    return 0; 
} 
+3

'while (fp)' wird immer wahr sein (vorausgesetzt, der Aufruf von 'fopen' ist erfolgreich). – Cornstalks

+0

Fügen Sie in Ihrer while-Schleife 'if (feof (fp)) break;' –

+0

@NickWhite hinzu: [Verwenden Sie nicht 'feof'] (http://stackoverflow.com/a/3181093/364696). Dateioperationen sollten im Allgemeinen das verwenden, was Python das EAFP-Muster nennt (Leichter Vergeben als Vergeben nach Erlaubnis); tun Sie, was Sie tun möchten, und behandeln Sie den Fehler. – ShadowRanger

Antwort

1

Ihr Problem ist:

while (fp) 

A FILE* ist, in einen Booleschen Test, nur ein weiterer Zeiger. So lange es erfolgreich geöffnet wurde, wird dieser Test immer bestanden. Sie lesen Zeichen immer wieder und speichern sie in aufeinanderfolgenden Elementen des Arrays, bis Sie überlaufen und schließlich ganz in den nicht zugewiesenen Speicher schreiben (oder zufälligerweise etwas Wichtiges stampfen und auf andere Weise einen Absturz verursachen).

Sie wollen wirklich so etwas wie:

// Must read into int; EOF itself is not a char value 
    int inchar; 
    // Read and test for EOF 
    while((inchar = fgetc(fp)) != EOF) 
    { 
     ch[i] = inchar; // Store 
     i++; 
     printf("%d", inchar); // Print raw value returned by fgetc 
    } 
+0

Ich habe gerade eine' while (1) 'Schleife hinzugefügt und' if (feof (fp)) break; '. –

+0

@KshitijBantupalli: Wie ich in den Kommentaren zu der Frage notiert habe, [verwende nicht 'feof'] (http://stackoverflow.com/a/3181093/364696); es sagt Ihnen nur, dass Sie das Ende der Datei erreicht haben, nachdem Sie Müll gelesen haben. 'fgetc' selbst wird ein Zeichen lesen und Ihnen sagen, ob es das Ende der Datei erreicht hat, also' feof' vergeudet nur Zyklen, die Flags prüfen, wenn 'fgetc' Ihnen bereits gesagt hat, was vor sich geht. – ShadowRanger

+1

@KshitijBantupalli: Um klar zu sein, die "While" -Schleife, die ich als ein Beispiel zur Verfügung gestellt habe, ist im Grunde der übliche Ansatz zum Lesen einer Datei um jeweils ein Zeichen; Die meisten Dokumente (z. B. die 'fgetc'-Dokumente von [cppreference.com] (http://en.cppreference.com/w/c/io/fgetc)) verwenden das exakt gleiche Muster. – ShadowRanger

1

Nachdem Sie "während (fp)" Problem zu beheben. Du hast immer noch Probleme mit ch [i]. Mit Ihrem Code wird "i" auf 400 erhöht. Daher tritt ein Segmentierungsfehler auf.

while(fp) 
    { 
     ch[i] = fgetc(fp); 
     i++; 
     j = i; 
     printf("%d", j);  
    } 
+0

Können Sie mir sagen, warum es auf 400 erhöht wird? –

+1

Sie haben zwei Schleifen in Ihrem Code. "while (count! = 0)" ist 100 mal. "while (fp)" wird 4 mal erwartet. 100 x 4 = 400. – stan

Verwandte Themen