2017-02-22 4 views
0

J'essaye d'écrire un simple programme C qui charge un fichier texte, imprime la première ligne à l'écran, attend que l'utilisateur appuie sur Entrée, puis imprime la ligne suivante, etc.C - Imprimer les lignes à partir du fichier avec getline()

Comme seul argument, il accepte un fichier texte qui est chargé en tant que "base de données" de flux. J'utilise la fonction getline() pour cela, selon l'exemple this. Il compile bien, charge avec succès le fichier texte, mais le programme ne pénètre jamais dans le while-loop, puis quitte.

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

FILE *database = NULL; // input file 

int main(int argc, char *argv[]) 
{ 
    /* assuming the user obeyed syntax and gave input-file as first argument*/ 
    char *input = argv[1]; 

    /* Initializing input/database file */ 
    database = fopen(input, "r"); 
    if(database == NULL) 
    { 
     fprintf(stderr, "Something went wrong with reading the database/input file. Does it exist?\n"); 
     exit(EXIT_FAILURE); 
    } 

    printf("INFO: database file %s loaded.\n", input); 

    /* Crucial part printing line after line */ 
    char *line = NULL; 
    size_t len = 0; 
    ssize_t read; 

    while((read = getline(&line, &len, database)) != -1) 
    { 
     printf("INFO: Retrieved line of length %zu :\n", read); 
     printf("%s \n", line); 
     char confirm; // wait for user keystroke to proceed 
     scanf("%c", &confirm); 
     // no need to do anything with "confirm" 
    } 

    /* tidy up */ 
    free(line); 
    fclose(database); 
    exit(EXIT_SUCCESS); 
} 

Je l'ai essayé avec fgets() - Je peux aussi poster ce code -, mais même chose là-bas: il ne pénètre jamais la boucle while.

Cela pourrait être quelque chose de très évident; Je suis nouveau à la programmation. J'utilise le compilateur gcc sur Kali Linux.

+1

Qu'est-ce qu'un débogueur vous indique lorsque vous parcourez le code? –

+0

Merci pour vos réponses; J'ai trouvé mon erreur. C'est vraiment embarrassant, parce que le code fonctionne, seul mon fichier texte a été mangé; peut-être que je ne l'ai pas fermé correctement et tout son contenu a été supprimé, donc bien sûr la valeur de getline() était EOF/-1. – c2ethanol

+0

Je voudrais également vérifier le retour de 'scanf()' ici, – RoadRunner

Répondre

1

Changez votre scanf avec fgetline en utilisant stdin comme paramètre de votre fichier.

1

Vous devez parcourir ceci dans un débogueur, pour vous assurer que votre affirmation selon laquelle il n'entre jamais dans la boucle while est correcte.

Si elle n'entre vraiment jamais dans la boucle while, c'est forcément parce que getline() a retourné -1. Soit le fichier est vraiment vide, soit vous avez une erreur de lecture du fichier.

man getline dit:

En cas de succès, getline() et getdelim() retourne le nombre de caractères lecture, y compris le caractère de séparation, mais ne comprenant pas le termi- nant octet nul ('\ 0 '). Cette valeur peut être utilisée pour gérer octets NULL dans la ligne lue.

Les deux fonctions renvoient -1 en cas d'échec de lecture d'une ligne (y compris la condition de fin de fichier ). En cas d'erreur, errno indique la cause.

Par conséquent, vous devez améliorer votre code pour vérifier les erreurs de flux et de traiter errno - vous devriez le faire même quand fonctionne votre code, car EOF n'est pas la seule raison de la fonction revenir -1.

int len = getline(&line, &len, database); 
    if(len == -1 && ferror(database)) { 
     perror("Error reading database"); 
    } 

Vous pouvez écrire un code plus détaillé pour traiter errno de manière plus explicite. Malheureusement, cela peut rendre votre code un peu plus bavard - bienvenue dans C!

-1

fonctionne bien sur ma plate-forme gcc ver.4.8.4 sur Ubuntu Linux. Quelle est votre version de gcc?

+0

Ceci n'est pas une réponse. – slim

+0

Bienvenue dans Stack Overflow. Je sais que c'est frustrant quand vous êtes nouveau et que vous ne pouvez pas ajouter de commentaires, mais si vous ajoutez un commentaire en guise de réponse, vos informations utiles seront rejetées. Il est préférable de patienter, d'acquérir la réputation requise (50 points) et, jusqu'à ce que vous ayez la réputation, fournissez de bonnes réponses aux (bonnes) questions où vous pouvez fournir une réponse réelle (ou poser de bonnes questions - bien que cela soit plus difficile façons). Les sections locales fourniront habituellement des commentaires semblables à celui-ci le cas échéant. –

+0

@JonathanLeffler Roger ça! – Vickey