IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Impossibilité de lire un fichier texte créé


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Lycéen
    Inscrit en
    Décembre 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Décembre 2007
    Messages : 37
    Par défaut Impossibilité de lire un fichier texte créé
    Bonjour!
    Je suis sous Linux et j'utilise Code::Blocks pour compiler mes programmes.
    Je débute en C et je fais les quelques exercices qu'il y a dans le livre de Delannoy mais j'ai un problème avec un exercice.
    C'est un exercice pour utiliser les commandes de création et d'écriture séquentielle d'un fichier.
    Le problème étant qu'une fois le fichier créé, s'il a été rempli via le programme, impossible de le lire.

    Voici mon programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #include <stdio.h>
    #include <string.h>
     
    main()
    {
        struct infos {char nom[21]; char prenom[16]; int age; char tel[10];};
        struct infos personne;
        char nomfich[21];
        FILE * sortie;
     
        printf("Donnez un nom à votre fichier : ");
        scanf("%20s", nomfich); getchar();
        sortie = fopen(nomfich, "w");
     
        while (1)
        {
            printf("\n");
            printf("Nom : "); gets(personne.nom);
            if(!strlen(personne.nom)) break;
     
            printf("Prénom : "); gets(personne.prenom);
     
            printf("Age : "); scanf("%3d", &personne.age); getchar();
     
            printf("Numéro de téléphone : "); gets(personne.tel);
     
            fwrite(&personne, sizeof(personne), 1, sortie);
        }
        fclose(sortie);
    }
    Et voici la solution donné par Delannoy :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    #include <stdio.h>
    #include <string.h>
    #define LGNOM 20
    #define LGPRENOM 15
    #define LGTEL 11
     
    main()
    {
        char nomfich[21];
        FILE * sortie;
        struct { char nom[LGNOM+1];
                 char prenom[LGPRENOM+1];
                 int age;
                 char tel[LGTEL+1];
                } bloc;
     
        printf("Donnez le nom du fichier à créer : ");
        gets(nomfich);
        sortie = fopen(nomfich, "w");
        printf("----- pour finir la saisie, donnez un nom vide -----\n");
        while(printf("Nom : "), gets(bloc.nom),strlen(bloc.nom))
        {
            printf("Prénom :");
            gets(bloc.prenom);
            printf("Age : ");
            scanf("%d", &bloc.age); getchar();
            printf("Téléphone : ");
            gets(bloc.tel);
            fwrite(&bloc, sizeof(bloc), 1, sortie);
        }
        fclose(sortie);
    }
    Ca bloque à partir du moment ou le tampon est écrit dans le fichier via la commande 'fclose' et en fait soit j'ai un fichier qu iest pris pour un fichier image masi impossible de le lire soit un fichier qui est strictement illisible, aucun programme n'est en mesure de me le lire...

    Merci de m'aider!

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par sdumasp Voir le message
    Voici mon programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
       char nomfich[21];
     
       scanf ("%20s", nomfich);
       getchar ();
    Correct, mais un peu 'bidouilleux'... En cas de dépassement, le flux n'est pas vidé, ce qui provoque une instabilité :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Donnez un nom Ó votre fichier : aaaaaaaaaaaaaaaaaaaaaaaaaa
     
    Nom : PrÚnom :
    Eviter les accentuées, ce n'est pas portable... Pour un exercice, on a pas besoin d'une présentation parfaite.
    Avec une bonne purge, ça va déjà mieux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Donnez un nom a votre fichier : aaaaaaaaaaaaaaaaaaaaaaa
     
    Nom :
    attention, fopen() peut échouer. Il faut tester la valeur retournée avant de l'utiliser (NULL = problème).

    Non. On utilise pas gets(). C'est un bug. Il n'y a aucun moyen de limiter le nombre de caractères entrés, et il y a donc un risque permanent de débordement de tableau.

    Tu avais pourtant bien commencé avec un usage plutôt correct de scanf() (ce qui est suffisamment rare pour être souligné...). Continue sur cette lancée, sauf si on t'a expressément demandé de saisir des lignes avec des espaces, dans ce cas, il faut utiliser fgets().

    Au fait, pour la 'ligne vide', il n'y pas le choix, il faut utiliser fgets(). Ni gets() ni scanf() ne fonctionnent sur une ligne vide.

    Pour fgets() qui prend aussi le '\n', il y a une petite manip de nettoyage à faire avant (voir la fonction 'communautaire' fclean(), maintes fois publiée sur le forum)... Je conseille par contre l'usage exclusif de fgets() pour toutes les saisies. Faire les conversion en numérique si nécessaire...

    Citation Envoyé par sdumasp Voir le message
    Et voici la solution donné par Delannoy :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        gets(nomfich);
     
        while(printf("Nom : "), gets(bloc.nom),strlen(bloc.nom))
     
            gets(bloc.prenom);
     
            gets(bloc.tel);
    }
    Voilà, entre autres, pourquoi je ne recommande pas les livres de C.Delannoy.

  3. #3
    Membre averti
    Profil pro
    Lycéen
    Inscrit en
    Décembre 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Décembre 2007
    Messages : 37
    Par défaut
    • comment faire pour purger correctement le tampon de scanf après récupération d'une saisie? il y a une commande spéciale?
    • en ce qui concerne la commande 'gets' c'est que j'ai pas mal retouché mon programme de départ histoire qu'il ressembleà celui de Delannoy (malheureusement aucun des deux ne fonctionnent...) et habituellement j'utilise fgets qui me permet de controller parfaitement la saisie et d'éviter des lignes de code supplémentaire pour vérifier s'il y a pas dépassement (parfois j'utilise gets+sscanf, je l'avoue , pour vérifier si le type saisi est correct)
    • les instructions dans les conditions de boucles?
      moi j'aime pas trop parce que j'arrive plus à lire mon code après alors j'évite et je préfère détailler à l'intérieur de la boucle



    (petite question subsidiaire qui n'a aucun rapport, comment inclure les libraires GTK et GTK+ à Code::Blocks? il veut pas me compiler mon truc quand j'inclus gtk/gtk+.h...)

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par sdumasp Voir le message
    comment faire pour purger correctement le tampon de scanf après récupération d'une saisie? il y a une commande spéciale?
    Non. On doit faire ceci :
    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void purge (void)
    {
       int c;
       while ((c = getchar ()) != '\n' && c != EOF)
       {
       }
    }
    en ce qui concerne la commande 'gets' c'est que j'ai pas mal retouché mon programme de départ histoire qu'il ressembleà celui de Delannoy (malheureusement aucun des deux ne fonctionnent...) et habituellement j'utilise fgets qui me permet de controller parfaitement la saisie et d'éviter des lignes de code supplémentaire pour vérifier s'il y a pas dépassement (parfois j'utilise gets+sscanf, je l'avoue , pour vérifier si le type saisi est correct)
    Je supose que tu veux dire "fgets() + sscanf()". Tu as raison, continue comme ça. Laisse tomber gets() (bug) et scanf() est trop fort pour toi, moi, ... et Delannoy !
    les instructions dans les conditions de boucles?
    moi j'aime pas trop parce que j'arrive plus à lire mon code après alors j'évite et je préfère détailler à l'intérieur de la boucle
    C'est carrément laid et illisible (Qui fait quoi ? Quand ?)
    (petite question subsidiaire qui n'a aucun rapport, comment inclure les libraires GTK et GTK+ à Code::Blocks? il veut pas me compiler mon truc quand j'inclus gtk/gtk+.h...)
    Il y a une procédure décrite dans la section GTK+.

  5. #5
    Membre averti
    Profil pro
    Lycéen
    Inscrit en
    Décembre 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Décembre 2007
    Messages : 37
    Par défaut
    oui oui pardon, je parlais de 'fgets()' et 'sscanf()'!!

    merci pour les explications et les astuces, ça permet d'être rigoureux et de faire des trucs lisibles et fonctionnels!
    cependant je ne pense pas que le problème vienne du programme vu que celui de Delannoy ne fonctionne pas non plus (à noter qu'il manque l'inclusion de string.h dans la correction!); je pense que ça vient plutôt de l'OS.

    quand au GTK+ la procédure est pour Windows et je suis sous Linux (Ubuntu) et je trouve rien de bien nulle part...

  6. #6
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par sdumasp Voir le message
    cependant je ne pense pas que le problème vienne du programme vu que celui de Delannoy ne fonctionne pas non plus (à noter qu'il manque l'inclusion de string.h dans la correction!); je pense que ça vient plutôt de l'OS.
    Je ne pense pas. Comment as-tu quitté le programme puisque la manip prévue (strlen(...)) ne fonctionne pas ?

    Si tu as fais un ctrl-break, il est possible que le fichier ne soit pas fermé correctement et qu'il soit donc de taille nulle.

    Je pense qu'un recodage à base de fgets() corrigera le problème.

    Sinon, problèmes de droits, de propriétaire etc. Effectivement, c'est l'OS.

  7. #7
    Candidat au Club
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    2
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 2
    Par défaut
    wi c une bonne question parceque jé trouvé le méme soucis . alors essayé avec un chemin trés court du féchier

    ex c:\le nom du fichier

  8. #8
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par emsist86 Voir le message
    wi c une bonne question parceque je trouvé le méme soucis . alors essayé de ne po un chemin trés long du féchier

    ex c:\lenom du fichier
    Tu peux le refaire en français ? Faut quand même pas exagérer là...

    J'ai modifié le code pour qu'il tienne compte automatiquement de la taille de
    Il suffit maintenent de l'agrandir,
    et de recompiler...
    Attention, si il y a des espaces dans le nom du fichier, il faut penser à encadrer le nom avec des " " :

    "mon fichier"

  9. #9
    Membre averti
    Profil pro
    Lycéen
    Inscrit en
    Décembre 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Décembre 2007
    Messages : 37
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    J'ai modifié le code pour qu'il tienne compte automatiquement de la taille de
    je ne comprend pas bien quel code a été modifié?!

    sinon même si le fichier n'est pas lisible directement par éditeur de texte, il l'est séquentiellement ou directement via un autre programme que je viens de faire.

    j'ai une petite question, dans un programme, une fois les fichiers fclean.h et fclean.c rajoutés au projet, y-a-t'il un moyen de m'éviter de me taper tout le chemin dans l'inclusion?
    je suis obligé de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #include "/home/sdumasp/Programmation/fclean.h"

  10. #10
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par sdumasp Voir le message
    je ne comprend pas bien quel code a été modifié?!
    http://www.developpez.net/forums/sho...7&postcount=12

    j'ai une petite question, dans un programme, une fois les fichiers fclean.h et fclean.c rajoutés au projet, y-a-t'il un moyen de m'éviter de me taper tout le chemin dans l'inclusion?
    je suis obligé de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #include "/home/sdumasp/Programmation/fclean.h"
    Ce n'est plus un problème de langage C mais d'outil.

    A toi de passer la bonne option :

    [gcc] : -I"./"

    détails dans la doc de gcc. Je conseille l'usage de make avec un fichier makefile.

    Si tu utilises un IDE comme Code::Blocks, il faut préciser ./ dans les chemins des 'includes'.

    Settings > Directories > Compiler etc.

    http://emmanuel-delahaye.developpez.com/make.htm

    Je suis sous Linux et j'utilise Code::Blocks pour compiler mes programmes.
    Apparemment, j'ai bien visé...

  11. #11
    Membre averti
    Profil pro
    Lycéen
    Inscrit en
    Décembre 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Décembre 2007
    Messages : 37
    Par défaut
    ok merci beaucoup!
    je continue sur ma lancée et puis j'ai aussi chopé quelques autres trucs supplémentaires notamment concernant la programmation en C sur Linux...

Discussions similaires

  1. Réponses: 2
    Dernier message: 05/12/2005, 15h57
  2. [Applet] lire un fichier texte
    Par lebesnec dans le forum Applets
    Réponses: 2
    Dernier message: 07/07/2005, 10h09
  3. Réponses: 1
    Dernier message: 24/11/2004, 16h54
  4. [Fichier] Lire un fichier texte long
    Par _Eric_ dans le forum Entrée/Sortie
    Réponses: 9
    Dernier message: 18/08/2004, 15h22
  5. Réponses: 2
    Dernier message: 26/05/2004, 17h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo