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 :

lire et écrire dans un fichier


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 8
    Points : 1
    Points
    1
    Par défaut lire et écrire dans un fichier
    Bonjour, je fais appel à vous parce que je suis un peu perdue: je connais bien le C++ mais là je fais un jeu en C pour un ami et du coup je nage... En fait je reste bloquée au moment ou je veux enregistrer les scores d'une partie à l'autre. Il faut pour ça que j'enregistre dans un fichier le score actuel, je veux noter aussi le meilleur score et le plus mauvais. Mais je ne connais pas la procédure pour ouvrir, lire et écrire sur un fichier en C. La procédure du C++ ne marche pas forcément...
    Donc si quelqu'un peut me donne run exemple...
    Merci

  2. #2
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 119
    Points
    28 119
    Par défaut
    Bonjour,

    il faut que tu te renseignes sur les fonctions suivantes :

    fopen ()
    ...
    fwrite ()
    ...
    fclose ()

    Pour lire, il faut utiliser fread ().
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  3. #3
    Membre habitué Avatar de Marco85
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 210
    Points : 187
    Points
    187
    Par défaut
    Salut karel,

    Jette un oeil ici.

    Marco85
    If you cannot explain a concept to a six year-old, then you do not fully understand it. [Albert Einstein]

  4. #4
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    merci beaucoup... à tous les deux. Et je lis dès maintenant le lien plus que pertinent que tu m'as donné ... Je risque de revenir pour des questions plus précises

  5. #5
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    si j'ai bien compris la fonction fgets ne lit que les char, donc pas question de l'utiliser pour mes scores... il faut donc que j'utilise plutôt read() c'est ça? mais que prend t elle en paramètres? Et puis-je lui demander de s'arrêter à chaque caractère retour charriot?

  6. #6
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    alors, j'ai bien compris comment ouvrir et lire, mais si je veux mettre la première ligne d'un fichier dans une variable, la deuxième dans une autre... comment dois-je faire? (si il y a encore un lien je veux bien, c'était très clair là, sauf la partie écriture mais je vais me débrouiller pour ça)... Merci d'avance

  7. #7
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Salut
    Tu peux utiliser un tableau de chaînes :
    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
    char tab[20][50]; // tu as ici un tableau de 20 lignes d'au maximum 49 caractères (il faut le zéro terminal
    char buf[50];
    char *p;
    FILE *f;
    int i = 0;
    // ouverture du fichier
    f = fopen("mon_fic.txt", "r");
    if (f == NULL)
    {
       // l'ouverture n'a pas pu se faire
      fprintf(stderr, "erreur ouverture mon_fic.txt\n");
      return <erreur_1>;
    }
    // tant qu'on lit des lignes
    while (fgets(buf, sizeof(buf), f) != NULL)
    {
      // on efface le '\n' laissé par fgets
      p = strchr(buf, '\n');
      if (p == NULL)
      {
      // fgets n'a pas lu le '\n', vraisemblablement le buffer de lecture 
      // est trop court
      // a toi de voir ce que tu veux faire
      }
      else
      // on vire le '\n'
         *p = 0;
      // on recopie dnas le tableau
      strcpy(tab[i], buf);
      i++;
    }
    fclose(f);
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  8. #8
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Bonjour Trap, merci à toi pour ta réponse qui m'a fait me poser de nouvelles questions:
    un tableau correspond à une QValueList du C++?
    Je peux donc très bien mettre plutôt: int tab[4][50];
    vu qu'il va s'agir exclusivement d'entrer les scores et statistiques...
    Enfin, encore une question, ça n'est pas clair dans la FAQ, si je ne veux pas utiliser fgets (vu que ce sont des scores dc des nombres) je voulais utiliser fread() mais je n'ai pas trouvé d'explications sur ce qu'il lui fallait en paramètres et comment ne lui faire lire qu'une ligne...
    Parce que si je fais un fgets et que je mets chaque ligne dans un int tab je vais avoir un pb de conversion...
    Voila mes interrogations, probablement stupides, mais merci à vous de votre aide....

  9. #9
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par karel
    un tableau correspond à une QValueList du C++?
    Vu que tu as "List" dans le nom, ça devrait te choquer comme ne pouvant pas être pareil qu'un tableau. Le C++ posséde aussi des tableaux comme le C.

    Citation Envoyé par karel
    Je peux donc très bien mettre plutôt: int tab[4][50];
    Si ton fichier possède au maximum 4 ligne de 50 entiers (ou 50 lignes de 4 entiers bien que ce ne serait pas logique de l'écrire comme ça).

    Citation Envoyé par karel
    vu qu'il va s'agir exclusivement d'entrer les scores et statistiques...
    A ce moment-là, des entiers semblent plus naturels.

    Citation Envoyé par karel
    Parce que si je fais un fgets et que je mets chaque ligne dans un int tab je vais avoir un pb de conversion...
    Pas vraiment, tu peux utiliser strtol pour faire tes conversions.

    Jc

  10. #10
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Oui sauf que les tableaux en C++ sont des QMap à deux éléments, et là je trouve que ce tableaux (sauf si j'ai mal compris ce qui est probable) n'a qu'une colonne... voila pourquoi je pensais au liste...

    en fait effectivement je devrais peut être plus mettre int tab [4] [5]?
    parce qu'il n'y aura qu'un chiffre par ligne, et il sera compris entre 0 et 1000... Donc en mettant 5, ça devrait jouer... ai-je bien compris?

  11. #11
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Première chose, ici on fait du C, donc oublie les notions et le vocabulaire C++.
    En C les listes sont souvent assmilées à de listes chaînées qui sont un outil très particulier, sinon on parle de tableaux.
    Dans le forum C tu auras des fonctions de lecture de texte ou de "binaire" point. En binaire il n'y a pas de notion de ligne.
    Autre chose maintenant, garde présent à l'esprit que tu liras comme tu écriras, ce qui veut dire qu'avant de lire tu auras du écrire tes données, et selon la méthode utilisée pour écrire tu auras une méthode appropriée pour lire.
    Tu peux utiliser fwrite et fread si tu veux, certains te diront que ce n'est pas très portable et ils ont raison, mais tu peux te poser la question est-ce nécessaire pour ce que je veux faire.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par karel
    si j'ai bien compris la fonction fgets ne lit que les char, donc pas question de l'utiliser pour mes scores...
    fgets() lit une ligne de texte. Si celle-ci représente des valeurs numériques, il suffit ensuite la 'parser' avec sscanf() ou strtol() et ses frères...

    Le format texte est pratique car

    - relativement assez simple à mettre en oeuvre
    - lisible
    - éditable avec un traitement de texte
    - très portable
    Pas de Wi-Fi à la maison : CPL

  13. #13
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    merci à tous pour vos réponses mais j'ai encore un soucis... en fait ma fonction donne ceci:

    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
    33
    int gereFichier() {
     
      int tab[10];
      FILE *fp = fopen("scores.txt", "r+b");
      if (fp == NULL)
     
      { // la première fois il doit le créer
     
        FILE *fp = fopen("scores.txt", "w+r+b"); 
        printf("fichier inexistant\n");
     
        tab[0]=cpt; // il faut initialiser les valeurs vu qu'il est vide
        tab[1]=cpt;
        tab[2]=1;
        }
     
    else { // sinon il compare et change les valeurs
        fread(tab, sizeof(int), 4, fp);
        if (cpt < tab[0]) tab[0] = cpt;
        if (cpt > tab[1]) tab[1] = cpt;
        tab[2] = tab[2]+1;
      }
     
    rewind(fp);
    fwrite(tab, sizeof(int), 4, fp); // ensuite on reremplit le fichier
     
    printf("Le nombre de coups minimum est %d\n",tab[0]); // test
    printf("Le nombre de coups maximum est %d\n",tab[1]);
    printf("Le nombre de coups moyen est %d\n",tab[2]);
     
    // on ferme le fichier
    fclose(fp);
    }
    Mais mon problème est le suivant: il créé bien le fichier la première fois mais n'écrit pas à l'intérieur, du coup le fichier reste vide...
    J'ai fait plusieurs tests comme:

    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
    33
    34
    35
    36
    37
    38
    39
    int gereFichier() {
     
      int tab[10];
      FILE *fp = fopen("scores.txt", "r+b");
      if (fp == NULL)
     
      { // la première fois il doit le créer
     
        FILE *fp = fopen("scores.txt", "w+r+b"); 
        printf("fichier inexistant\n");
     
        tab[0]=cpt; // il faut initialiser les valeurs vu qu'il est vide
        tab[1]=cpt;
        tab[2]=1;
     
    fwrite(tab, sizeof(int), 4, fp); // ensuite on remplit le fichier
     
    printf("Le nombre de coups minimum est %d\n",tab[0]); // test
    printf("Le nombre de coups maximum est %d\n",tab[1]);
    printf("Le nombre de coups moyen est %d\n",tab[2]);
        }
     
    else { // sinon il compare et change les valeurs
        fread(tab, sizeof(int), 4, fp);
        if (cpt < tab[0]) tab[0] = cpt;
        if (cpt > tab[1]) tab[1] = cpt;
        tab[2] = tab[2]+1;
     
    rewind(fp);
    fwrite(tab, sizeof(int), 4, fp); // ensuite on reremplit le fichier
     
    printf("Le nombre de coups minimum est %d\n",tab[0]); // test
    printf("Le nombre de coups maximum est %d\n",tab[1]);
    printf("Le nombre de coups moyen est %d\n",tab[2]);
      }
     
    // on ferme le fichier
    fclose(fp);
    }
    Mais là il me parle d'une erreur de conversion... et ne le remplit toujours pas... donc si qq'un a une idée... merci bcp... Peut être effectivement que si je change le fread en fgets... bref je ne sais pas trop. Merci d'avance

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FILE *fp = fopen("scores.txt", "w+r+b");
    Euh... ça existe, le mode w+r+b ?
    Je ne sais pas trop ce que c'est supposé faire quand on cumule w+ et r+... Généralement w+ suffit, non?

    Et aussi, quand quelque chose ne marche pas, on passe en mode débogage intensif: On regarde attentivement TOUS les retours de fonction, (ainsi que la valeur d'erreur errno) pour voir ce qui a foiré ou non...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  15. #15
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Quelques remarques sur ton code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int gereFichier() {
    Tu mets un type de retour mais il n'y a pas de return dans ta fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    FILE *fp = fopen("scores.txt", "w+r+b");
    Voir la remarque de Médinoc pour ta chaîne "w+r+", "w+" suffirait... Plus grave, tu as redéclarais la variable fp. Lorsque tu sortiras de ce bloc, la valeur de ce fp sera perdu et l'ancienne valeur reviendra (donc NULL). C'est ici ton plus grand problème.

    Autre détail, tu ne vérifies pas le retour de ce fopen.

    Tu dis que tab[2] contient le nombre de coups moyen, pourquoi est-ce qu'il vaut 1 ici?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fread(tab, sizeof(int), 4, fp);
    Pourquoi 4? Tu n'en utilises que 3...

    Jc

  16. #16
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    merci à tous pour vos conseils précieux et vos remarques, tout marche très bien maintenant... effectivement, mettre int au lieu de void n'était pas très heureux... Expérience très enrichissante de passer au C... à refaire

Discussions similaires

  1. lire et écrire dans un fichier
    Par aroua dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 04/04/2008, 14h44
  2. Lire et écrire dans un fichier binaire
    Par poche dans le forum C
    Réponses: 17
    Dernier message: 19/03/2007, 16h52
  3. Lire et écrire dans un fichier bin!
    Par poche dans le forum C
    Réponses: 9
    Dernier message: 12/03/2007, 12h42
  4. [FTP] Lire et écrire dans un fichier
    Par dj-julio dans le forum Langage
    Réponses: 49
    Dernier message: 12/01/2006, 11h59
  5. [Rech. Comp.] Lire et écrire dans des fichiers XML
    Par Rodrigue dans le forum C++Builder
    Réponses: 4
    Dernier message: 26/08/2005, 20h48

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