2016-05-06 20 views
3

Ich versuche, fgets() innerhalb einer Funktion namens "a_function()" auszuführen.fgets() verhält sich unerwartet außerhalb von main()

int a_function(){ 
    char* str; 
    FILE *fp; 

    fp = fopen("./file.txt", "r"); 
    if(NULL != fp){ 
     fgets(str, 6, fp); 
     printf("%s\n", str); 
    }else{ 
     printf("cannot find file\n"); 
     return 1; 
    } 
    return 0; 
} 

int main(void){ 

    a_function(); 

    return 0; 

} 

Dies führt jedoch zu einem segfault, der auftritt, wenn die Funktion fgets() aufgerufen wird. Interessanterweise kann ich wörtlich meinen Code von a_function in meine main() Funktion und alles läuft gut kopieren:

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

int a_function(){ 

    return 0; 
} 

int main(void){ 

    a_function(); 
    char* str; 
    FILE *fp; 

    fp = fopen("./file.txt", "r"); 
    if(NULL != fp){ 
     fgets(str, 6, fp); 
     printf("%s\n", str); 
    }else{ 
     printf("cannot find file\n"); 
     return 1; 
    } 
    return 0; 

} 

Der Code über kompiliert wird:

gcc -g -std=c11 test.c -o test 

Was ich hier fehlt? Ist es ein Problem mit meinem Code oder mit meinem Computer? Jede Hilfe wird geschätzt. Danke

+0

Tipp: Wo du gesagt hast 'fgets' die Zeichenfolge zu speichern, es liest? – immibis

+0

'str' muss malloced oder zu einem normalen char [] – Turtle

Antwort

5
char* str; 
fgets(str, 6, fp); 

In beiden Fällen Sie obigen Code tun, hier str nicht initialisiert wird, der unbestimmten Wert enthält, der Eingabe es nicht definiertes Verhalten verursachen. Beide Fälle sind falsch, auch stürzt es manchmal nicht ab.

Versuchen Sie wie folgt vor:

char str[6]; 
fgets(str, sizeof str, fp); 
+0

gemacht werden Vielen Dank! Das schien das Problem zu sein. Ich frage mich, warum es in main() funktioniert hat? –

+0

@ J.Doe Es ist UB egal, es hat manchmal funktioniert, es ist nur durch Zufall. Wir sollten robusten Code schreiben, anstatt uns auf gefährliche Verhaltensweisen zu verlassen. :) – fluter

+0

@ J.Doe: Flattern ist richtig: Die Tatsache, dass Ihr Code überhaupt funktioniert hat, ist ein kleines Wunder. Sie können Daten nicht über einen nicht initialisierten Zeiger zuweisen. Eine weitere Option neben der Fluter-Lösung ist die Verwendung von 'malloc'. –

2

str ist nicht initialisiert, d.h. es zeigt nicht auf gültigen Speicher. So führt die fgets zu undefiniertem Verhalten.

es zu beheben, ändern char* str zu char str[6];