2014-03-19 17 views
6

Ich war in C einfache Datei versucht, die Handhabung und ich wollte sicherstellen, dass die Datei versucht das zugegriffen werden kann, mitfclose() verursacht Segmentation Fault

#include<stdio.h> 

main() 
{ 
    CheckFile(); 
} 

int CheckFile() 
{ 
    int checkfile=0; 

    FILE *fp1; 
    fp1 = fopen("users.sav","r"); 

    if(fp1==NULL) 
    { 
     fopen("users.sav","w"); 
     fclose(fp1); 
    } 
    if(checkfile!=0)printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);exit(1); 
    return 0; 
} 

dann zeigt es

Segmentation fault (core dumped) 

aber es segmet nicht, wenn die Datei bereits existiert (zB wenn ich sie manuell erstellt habe oder wenn ich das Programm das zweite Mal starte)

Bitte helfen Sie. Ich brauche das für unser Abschlussprojekt in einer Woche und ich habe noch nicht den Überblick über Dateien und Hinweise.

Ich bin mit "gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1"

P. S

Ich weiß, dass es scheinbar ähnliche Fragen besteht aber bitte nicht downvote. Verstehe, dass ich seit ein paar Monaten mit dem Codieren angefangen habe und deshalb diese erweiterten Codes und Sachen nicht verstehen kann.

pps

sah ich diese in einer anderen Frage

Es gibt keine Garantie in Ihrem ursprünglichen Code, die fopen tatsächlich funktioniert, wobei in diesem Fall wird es NULL zurück und die fclose nicht Verhalten definiert werden .

Also wie genau überprüfe ich, ob es funktioniert hat?

+2

Die Prüfung korrekt ist, einfach nicht 'fclose (FP1)' 'wenn fp1 == NULL' aber' nennen fp1 = fopen (..., "w"); ' –

+0

Thanks :) Die Antworten hat mir wirklich geholfen Coding läuft bisher reibungslos. – user3437503

+0

Mögliches Duplikat von [fclose() verursacht Segmentierungsfehler] (http://stackoverflow.com/questions/1443164/fclose-causing-segmentierung-fault) –

Antwort

1

fopen gibt einen FILE Zeiger zurück. Es wird NULL zurückgeben und den globalen errno festlegen, um den Fehler anzuzeigen. Wenn Sie die errno überprüfen möchten, müssen Sie überprüfen, ob nach NULL zurückgegeben.

if (fp1 == NULL) 
{ 
    printf("fopen failed, errno = %d\n", errno); 
} 

Andernfalls können Sie eine errno von etwas anderes bekommen, nicht unbedingt Ihre fopen Anruf. Enthalten Sie auch errno.h. Sie müssen auch nicht erneut fopen("users.sav","w"); aufrufen. Sie weisen den Zeiger weder erneut zu, noch überprüfen Sie ihn erneut.

Ich sehe keinen Grund, fclose hier zu nennen, da NULL zurückgibt, gibt es nichts zu schließen. Das ist wahrscheinlich der Grund für Ihren Seg Fehler. Sie versuchen, einen Nullzeiger zu schließen. More information on fopen failures.

Ein weiterer Kommentar zu Ihrem Code. Wenn Sie eine int von CheckFile zurückgeben, sollte es wahrscheinlich nicht 0 on fail sein. Ich würde -1 zurückgeben, um einen Fehler anzuzeigen. Besser noch, Sie könnten die globale errno zurückgeben. Außerdem sollte mainint main() sein und Sie sollten return 0; am Ende. Ich interessiere mich nicht besonders für Ihr Namensschema von CheckFile. In C wäre check_file oder camelCase von checkFile besser.

In CheckFile, Ihre eine Zeile if Anweisung könnte formatiert werden und funktionieren ordnungsgemäß, wenn Sie es in mehreren Zeilen formatiert.Es tut nicht das, was Sie denken, es tut zur Zeit:

if(checkfile!=0) 
{ 
    printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n", checkfile); 
    exit(1); 
} 

Auch checkfile wird nie irgendwo im Code .. andere als Null gesetzt. Also wird der Code in der if Anweisung nicht ausgeführt, Punkt.

4

Das ist normal, wenn Sie fclose(fp1) aufrufen, wenn fp1 NULL ist.

BTW

fopen("users.sav","w"); 

ist nutzlos, weil Sie nicht den Rückgabewert einer Zeigerdatei zuweisen. Das bedeutet, dass die Datei users.sav zum Schreiben geöffnet wird, Sie aber nie etwas darin schreiben können.

0

Der Mann Seite von fclose sagt -

Das Verhalten von fclose() ist nicht definiert, wenn der Strom-Parameter ein illegal Zeiger ist, oder ist ein Descriptor bereits zu einem früheren Aufruf von fclose() übergeben .

Der Fehler ist in der if Block in Ihrem Code.

if(fp1==NULL) 
{ 
    fopen("users.sav","w"); 
    fclose(fp1); // passing NULL to fclose invokes undefined behaviour 
} 
1

Ich bin nicht wirklich sicher, was Sie zu tun versuchen, aber das unmittelbare Problem ist hier:

if(fp1==NULL) 
    fclose(fp1); 

Nach dieser fp1 behauptet werden NULL, Sie versuchen close zu rufen der Nullzeiger, der einen Segmentierungsfehler verursacht.

Wenn alles, was Sie tun möchten, ist sicherzustellen, dass die Datei vorhanden ist, versuchen Sie so etwas wie What's the best way to check if a file exists in C? (cross platform)

+0

Danke .... Eine der Antworten dort half sehr. – user3437503

0

Ein weiteres unabhängiges Problem:

Diese Linie ist wahrscheinlich nicht das, was Sie wollen:

if(checkfile!=0)printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);exit(1); 

Wenn wir schreiben es richtig formatiert der Fehler wird offensichtlich:

if (checkfile != 0) 
    printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile); 

exit(1); 
return 0 ; 

Tatsächlich werden wir exit(1) erreichen, auch wenn checkfile Null ist.

Sie wollen wahrscheinlich diese:

if (checkfile != 0) 
{ 
    printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile); 
    exit(1); 
} 

return 0 ; 

Fazit: Format Code korrekt und viele Fehler wird plötzlich klar aussehen.

+0

Sie sollten dies wahrscheinlich in Ihre andere Antwort rollen, guter Fang :) – Brian

+0

@GIJoe: Nun, ich war mir nicht sicher, ob ich das getan hätte, weil dieses Problem völlig unabhängig von der ursprünglichen Frage ist. –

+0

Ich würde .. macht Ihre Antwort stärker. – Brian