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 une ligne spécifique et envoyer les données vers une structure


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Ingénieur du son
    Inscrit en
    Janvier 2017
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur du son

    Informations forums :
    Inscription : Janvier 2017
    Messages : 12
    Points : 7
    Points
    7
    Par défaut lire une ligne spécifique et envoyer les données vers une structure
    Bonsoir,
    j'essaye de charger des données d'un fichier txt. Mon problème étant que je voudrais qu'une ligne corresponde à un monstre de mon jeu : en spécifiant la ligne on tombe sur le bon monstre.
    Après pas mal de recherche sur internet, j'ai trouvé pas mal de réponse, mais aucune ne me "rassasie".
    En fait j'aimerai utiliser un scanf avec un parametre de ligne à spécifier à ma fonction. (pour l'instant j'ai cru comprendre qu'il fallait utiliser fgets pour cela, mais son utilisation m'échappe...)
    Un petit indice (vu que les commandes qui concernent les fichier txt ne sont vraiment pas ma tasse de thé)? ^^

    Voici pour l'instant ma fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void ChargementInfoMob1(Mob *x)
    {
        FILE *monstre;
        monstre = fopen("monstre.txt", "r");
        fscanf(monstre, "%d %d %d %d %d %d %d %d %d %d %d %d %d" , &x->categorieMob, &x->positionX, &x->positionY, &x->mobWidth, &x->mobHeight, 
               &x->vieMob, &x->vieMaxMob, &x->niveauMob, &x->forceMob, &x->enduranceMob, &x->dexteriteMob, &x->intelligenceMob, &x->ruseMob);
        fclose(monstre);
    }

  2. #2
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Avant tout, voici deux conseils d'ordre général :

    • La documentation des fonctions de la bibliothèque C est disponible au sein des pages de manuel du système sur un OS Unix via man 3 fgets, par exemple. Elle est également disponible en ligne, entre autres sur cppreference. Cette référence est fondamentale, familiarise-toi avec son utilisation. Lorsque plane un doute sur le comportement d'une fonction, c'est elle qui a le dernier mot.
    • Vérifie errno et / ou le code de retour de toutes les fonctions d'entrée / sortie. Toujours. Ci-dessus, tu pars du principe que le fichier a bien été trouvé, ouvert, lu, et qu'on y a trouvé ce qu'on y cherchait. C'est valable également pour tous les autres appels système mais c'est encore plus important lorsque l'on traite des données qui proviennent de l'extérieur du programme.


    En ce qui concerne ton problème présent : il est difficile d'utiliser fscanf pour lire le contenu d'un flux de manière robuste, particulièrement lorsqu'il s'agit d'un fichier formaté « à la ligne ». En somme, je le te déconseille. Si tu veux tout de même te lancer, lis et relis la page de man de la fonction pour tenter d'appréhender tous les cas foireux qui peuvent survenir.

    Je te recommande plutôt d'utiliser fgets pour lire les lignes, puis sscanf pour les analyser. Je ne vais pas paraphraser les pages de manuel de ces fonctions ni les tutoriels du site maintenant. Lis-les, essaie quelque chose et si un truc t'échappe, nous t'aiderons.

    Une remarque : définir et implémenter son propre format de sérialisation est un bon exercice, mais ça vaut rarement le coup de se lancer là-dedans pour un projet « sérieux » ; à terme il faudra penser à utiliser une solution plus robuste. Il y en a pléthore : xml, json.. perso j'aime bien yaml.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Ingénieur du son
    Inscrit en
    Janvier 2017
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur du son

    Informations forums :
    Inscription : Janvier 2017
    Messages : 12
    Points : 7
    Points
    7
    Par défaut
    Merci pour ta réponse, le sscanf était effectivement ce que je recherchais.
    Petite question : pourquoi le .txt n'est pas bien pour un projet? Pour utiliser un xml?

    Voici le code :
    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
    void ChargementInfoMob(Mob *x, int lineFile)
    {
        char ligne[100];
        int i = 0;
        FILE *monstre = fopen("monstre.txt", "r");
        if (monstre == NULL)
        {
            puts("Probleme ouverture du fichier monstre.txt");
            exit(0);
        }
     
        while (fgets(ligne, 100, monstre) != NULL)
        {
            if (fgetc(monstre == '\n'))
            {
                 i++;
            }
            if (i == lineFile)
            {
                if (sscanf(ligne, "%d %d %d %d %d %d %d %d %d %d %d %d %d", &x->categorie, &x->positionX, &x->positionY,
                    &x->mobWidth, &x->mobHeight, &x->vieMob, &x->vieMaxMob, &x->niveauMob, &x->forceMob,
                    &x->enduranceMob, &x->dexteriteMob, &x->intelligenceMob, &x->ruseMob) != 13)
                {
                    puts("Probleme de format de ligne incorrect");
                }
            }
        }
        fclose(monstre);
    }

  4. #4
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    C'est pas trop mal, tout ça.

    Quelques petites remarques en vrac :

    • if (fgetc(monstre == '\n')) WAAAT? Tu sors ça d'où ? Vire-moi cette horreur, je mets ça sur le compte de la fatigue.
    • fgets peut renvoyer NULL pour deux raisons : EOF ou à cause d'une erreur d'entrée / sortie. Il faut tester ce cas via feof comme l'indique l'exemple sur cppreference.
    • Dans ton exemple, garde en tête que si la ligne fait plus de 98 octets (caractère de fin de ligne exclu), fgets retournera sans l'avoir parcourue en entier.
    • La responsabilité d'ouvrir et de fermer le fichier pourrait être déléguée à la portée appelante. En effet, si on a plusieurs entrées à lire, c'est inefficace de réaliser ces opérations plusieurs fois.
    • Plutôt qu'int, il est préférable d'utiliser size_t pour les compteurs. C'est un détail, mais une bonne habitude à prendre.


    Compile en activant tous les warnings : -std=c11 -pedantic -Wall -Wextra pour gcc par exemple (et clang, par extension).


    Citation Envoyé par edenstark Voir le message
    Petite question : pourquoi le .txt n'est pas bien pour un projet? Pour utiliser un xml?
    Parce que parser un fichier texte de manière robuste (sans craquer au premier espace en trop), c'est long, difficile et fastidieux. De plus, se limiter à un format personnalisé, c'est s'interdire l'échange de données avec d'autres applications. Pour toutes ces raisons, et d'autres encore, on utilise de préférence des formats et des implémentations (bibliothèques) bien établis et éprouvés.

  5. #5
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 110
    Points
    6 110
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Compile en activant tous les warnings : -std=c11 -pedantic -Wall -Wextra pour gcc par exemple (et clang, par extension).
    Juste pour pinailler :
    Dans GCC et CLang, il ne s'agit pas de tous les avertissements mais des avertissements principaux.
    Dans GCC, la majorité des avertissements sont documentées là : https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
    Dans CLang, il existe -Weverything qui n'existe pas dans GCC. Mais n'ai pas encore testé CLang. Je ne sais pas encore si -Weverything est adapté ou bien s'il va trop loin.

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Ingénieur du son
    Inscrit en
    Janvier 2017
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur du son

    Informations forums :
    Inscription : Janvier 2017
    Messages : 12
    Points : 7
    Points
    7
    Par défaut
    Bonsoir et merci pour vos réponses !

    Concernant l'erreur dont on ne doit pas prononcer le nom... Effectivement, petite fatigue et reliquat de tests précédents ^^.
    Je ne savais pour la fin de fichier, je m'efforcerai donc de tester maintenant avec feof.
    Pour l'ouverture du fichier, je ne testais qu'avec un seul monstre, mais effectivement maintenant que j'en ai rajouté plusieurs sur la map, cela me semble être une très bonne remarque.
    Pour les warnings, étant encore débutant, c'est vrai que je n'ai pas encore le réflexe de m'y intéresser. Mais bon faut bien s'y mettre, allez un peu de lecture pour ce week end ^^.

  7. #7
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par Pyramidev Voir le message
    Dans GCC et CLang, il ne s'agit pas de tous les avertissements mais des avertissements principaux.
    Tout-à-fait, il ne s'agit (malgré le nommage malheureux des options comme -Wall.. ) que des avertissements les plus utiles / communs. C'était un abus de langage de ma part et tu as raison de le préciser.


    Citation Envoyé par edenstark Voir le message
    Pour les warnings, étant encore débutant, c'est vrai que je n'ai pas encore le réflexe de m'y intéresser. Mais bon faut bien s'y mettre, allez un peu de lecture pour ce week end ^^.
    Je suis conscient que ça fait beaucoup de choses en peu de temps mais la philosophie derrière le langage C part du principe que tu sais ce que tu fais, or ce n'est pas le cas quand tu commences l'apprentissage de la programmation. Un avertissement du compilateur lorsque l'on débute, c'est pratiquement toujours mauvais signe si l'on excepte de rares cas bénins comme unused variable... Mieux vaut être confronté à un défaut en amont plutôt qu'aux dégâts qu'il aura causé bien après.

    Je te conseille carrément d'ajouter -Werror en sus des options déjà citées : ce flag « transforme » les messages d'avertissement en erreurs pures et simples, interrompant ainsi le processus de construction de l'exécutable et te forçant à corriger ton programme.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 07/09/2015, 11h11
  2. Réponses: 0
    Dernier message: 09/08/2013, 20h52
  3. Réponses: 13
    Dernier message: 02/02/2010, 12h02
  4. modifier les données d'une ligne d'un fichier
    Par racnet dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 07/01/2009, 16h17
  5. Réponses: 2
    Dernier message: 11/04/2007, 17h44

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