2016-09-20 3 views
0

Je veux créer ma propre version de la fonction fgets(). J'ai essayé de le faire mais j'ai eu quelques problèmes. S'il vous plaît laissez-moi savoir où je me trompe.Ecrire ma propre version de 'fgets()' dans C

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

char *my_fgets(char my_string[], int bytes, const char *filename) { 
    int i = 0; 
    FILE *fp; 

    if ((fp = fopen(filename, "wb")) == NULL) { 
     fprintf(stderr,"Couldn't open the file"); 
     return NULL; 
    } 

    while (sizeof(my_string) < bytes || my_string[i] != '\n') 
     my_string[i++] = getc(fp); 

    my_string[i] = '\0';  //adding NULL character at the end 

    /* using pointers 
    char *p; 
    for (p = array; p < array + bytes; p++) 
     *p = getc(fp);  
    *p = '\0'; */  

    fclose(fp); 
    return my_string;  
} 

int main() { 
    char my_string[15]; 
    int n; 
    char *p; 

    p = my_fgets(my_string, sizeof(my_string), stdin);  

    printf("\n%s", my_string); 
    printf("\n%s", p); 

    return 0; 
} 

Ma sortie n'est pas en cours d'exécution, elle se bloque immédiatement. Toute aide serait appréciée.

+3

standard 'fgets()' ne pas ouvrir un fichier; à moins que vous n'ayez reçu des restrictions d'un tuteur, le vôtre ne devrait pas l'être non plus. –

+6

Notez que la boucle avec 'while (sizeof (my_string)

+0

Je vais éditer cette partie et mettre 'strlen' à la place. merci – tadm123

Répondre

5

Votre mise en œuvre de fgets() a de nombreux problèmes majeurs:

  • Le prototype est incorrect: le dernier argument doit être un pointeur de flux (FILE *), et non pas un nom de fichier (const char *). Vous appelez votre fonction avec stdin, qui est en effet un flux pas un nom de fichier. Le compilateur devrait produire un avertissement pour cette erreur. À mon humble avis cet avertissement devrait être une erreur. Activez tous les avertissements du compilateur et ne les ignorez pas: gcc -Wall -W -Werror.

  • Pour ouvrir un fichier pour la lecture sous forme de texte, vous devez utiliser une chaîne de mode de "r", non "wb" qui tronque le fichier, mais étant donné que la fonction doit recevoir un FILE *, cela est discutable.

  • Le test en while (sizeof(my_string) < bytes || my_string[i] != '\n') est incorrect pour plusieurs raisons: vous devez comparer i avec la taille du tableau, et non sizeof(my_string) qui une constante, la taille d'un pointeur, et vous devez comparer l'octet lu à partir du fichier, pas my_string[i] à que vous n'avez encore rien stocké. En outre, vous devez utiliser l'opérateur logique et (&&) pour combiner ces tests, non logiques ou (||).

  • Le '\n' final doit être stocké dans la matrice de destination.

  • Vous ne renvoyez pas NULL à la fin du fichier.

  • Vous ne gérez pas le cas particulier d'une taille de tampon nulle.

Voici une version améliorée:

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

char *my_fgets(char my_string[], int bytes, FILE *fp) { 
    int c, i = 0; 

    if (bytes <= 0) 
     return my_string; 

    while (i < bytes - 1 && ((c = getc(fp)) != EOF) { 
     my_string[i++] = c; 
     if (c == '\n') 
      break; 
    } 
    my_string[i] = '\0'; //adding NUL character at the end 

    if (i > 0) { 
     return my_string; 
    } else { 
     return NULL; // no character read at end of file 
    } 
} 

int main(void) { 
    char my_string[15]; 
    int n; 
    char *p; 

    p = my_fgets(my_string, sizeof(my_string), stdin); 

    printf("%s\n", my_string); 
    printf("%s\n", p); 

    return 0; 
} 
+0

Merci beaucoup pour l'explication détaillée, je vais y aller attentivement. – tadm123