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 :

Problème dans une fonction pour lecture de fichiers .txt et répertoriage dans un tableau


Sujet :

C#

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2020
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2020
    Messages : 23
    Points : 20
    Points
    20
    Par défaut Problème dans une fonction pour lecture de fichiers .txt et répertoriage dans un tableau
    Bonjour à tous !

    Je me permet de vous solliciter car je bloque sur une fonction que je n'arrive pas à faire fonctionner comme je le souhaite. Il est possible que la conception même de la fonction ne convienne pas à ce que je souhaite faire.

    Cette fonction intervient dans le cadre d'un programme de jeu de Quizz que je dev en ce moment pour m'entraîner. Je signal que j'ai commencé le dev y a 2 mois et demi, donc soyez indulgents

    La voici, avec le commentaire qui va bien pour vous aider à vous comprendre ce que je souhaite faire, et ensuite je vous explique ce qui pose problème :

    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
     
    public static Theme[] ReadFromDirectory(string directoryPath)
            {
                //Comptage des fichiers dans le dossier, pour préparer la dimension du tableau
                var filesCount = (from file in Directory.EnumerateFiles(directoryPath, "*.txt", SearchOption.AllDirectories) select file).Count();
     
                //Variable qui servira de nombre de "cases" que contiendra le tableau. La taille du tableau. Elle est égale au nombre de fichiers.
                int i = filesCount;
     
                //Le tableau de type class "Theme".
                Theme[] themes = new Theme[i];
     
                //Récupérations des fichiers
                var files = Directory.EnumerateFiles(directoryPath, "*.txt");
     
     
                int numbering = 0;//Variable qui permettera de numéroter les thèmes du quizz par ordre croissant.
                foreach (var file in files)
                {
                    //Pour chaque fichier, lecture des lignes contenues dans le fichier.
                    var lines = File.ReadAllLines(file);
     
                    foreach (var line in lines)
                    {
                        if (line.Contains("thème"))//Pour chaque ligne, séléctionner celles contenant le mot "thème".
                        {
                            int found = line.IndexOf(": ");//Pour chaque ligne contenant le mot "thème", on extrait le nom du thème à cet indice.
                            Theme theme = new Theme(numbering++, line.Substring(found + 2));//Instanciation de la classe lié au theme.
                            for (i = 0; i < themes.Length; i++)
                            {
                                themes[i] = theme;//Pour chaque thème extrait, on le stock dans une case du tableau
                            }
                           Console.WriteLine($"{numbering}: {line}");//On verifie, visuellement, que le tout marche bien
                        }
                    }
                }
                return themes;//On renvoi les 2 thèmes.
            }
    J'ai donc 2 fichiers dans le dossier, donc 2 thèmes, "Jeux Vidéo" et "Manga", sous forme "chaîne de caractères", à stocker dans mon tableau, tout simplement.

    Sauf que mon soucis, c'est que je me retrouve au final, avec 2 fois le thème "Manga" dans les 2 slots du tableaux, au lieu de "Jeux Vidéo" d'abord, puis "Manga" (dans l'ordre de lecture des fichiers).

    Avec le débogage, j'ai compris ce qu'il se passe. En fait, quand ma fonction boucle, elle boucle d'abord sur le premier fichier, donc elle stock deux fois le premier thème "Jeux Vidéo" dans le tableau, puis boucle sur le second fichier, écrase le premier thème pour stocker à la place le thème "Manga" dans les deux slots.

    J'ai donc à la fin deux fois "Manga", au lieux des deux thèmes. Et je n'arrive pas à trouver la solution.

    J'ai beau tenter de sortir les boucles, supprimer l'une des boucles, mettre un "break", bref j'ai tâtonné à mort mais là je rend les armes, j'en peux plus xD

    Je sais pas si j'ai été clair, mais je reste à votre disposition si besoin, et merci par avance de votre aide !

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 197
    Points : 12 772
    Points
    12 772
    Par défaut
    Bonjour,
    Dans ta boucle, ligne 29 à 32, tu affectes le thème à tout le tableau.
    A mon avis tu devrais l'ajouter au tableau une seule fois, par exemple après la ligne 28. Mais sans boucler sur tous les éléments du tableau.

    Tatayo.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2020
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2020
    Messages : 23
    Points : 20
    Points
    20
    Par défaut
    Citation Envoyé par tatayo Voir le message
    Bonjour,
    Dans ta boucle, ligne 29 à 32, tu affectes le thème à tout le tableau.
    A mon avis tu devrais l'ajouter au tableau une seule fois, par exemple après la ligne 28. Mais sans boucler sur tous les éléments du tableau.

    Tatayo.
    Salut Tatayo !

    Merci pour ta réponse.

    Alors effectivement, c'est une bonne piste que j'ai exploré, en mettant donc "i < 1" au lieu de "i < themes.Lentgh" dans la boucle "for", et ça boucle bien qu'une fois par fichier, plutôt que 2 fois auparavant.
    Seulement, quand la deuxième boucle arrive, elle écrase le premier thème stocké dans l'indice 0 du tableau. L'indice 1 n'étant plus jamais sollicité.

    Je sens qu'on y est presque, mais je me retrouve toujours avec le thème "Manga", mais une seule fois au lieu de 2.

    Ce qu'il faudrait c'est que le thème "Jeu Vidéo" se stock dans l'indice 0, et "Manga" dans l'indice 1 du tableau. Comment faire avec ma fonction?

    EDIT : En fait il faudrait que "i" ne reparte pas de zero quand la 2ème boucle démarre, mais comment faire avec une boucle "for"? Je crois que je suis dans une impasse là?

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 197
    Points : 12 772
    Points
    12 772
    Par défaut
    En fait il ne faut pas faire de boucle, mais ajouter "une fois pour toute" chaque thème.
    Je ne sais pas quel IDE tu utilises, mais je pense qu'il permet de poser des point d'arrêt.
    Donc le mieux ici est d'en poser, et d'avancer pas à pas. Tu verras alors ce qu'il se passe.
    Je vois aussi que tu dimensions déjà le tableau lors de sa création.
    Donc enlèves directement le for, incrémente i (et profites en pour lui donner un vrai nom), et incrémentes le à chaque fichier (puisque visiblement un fichier = un thème).

    Tatayo.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2020
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2020
    Messages : 23
    Points : 20
    Points
    20
    Par défaut
    Citation Envoyé par tatayo Voir le message
    En fait il ne faut pas faire de boucle, mais ajouter "une fois pour toute" chaque thème.
    Je ne sais pas quel IDE tu utilises, mais je pense qu'il permet de poser des point d'arrêt.
    Donc le mieux ici est d'en poser, et d'avancer pas à pas. Tu verras alors ce qu'il se passe.
    Je vois aussi que tu dimensions déjà le tableau lors de sa création.
    Donc enlèves directement le for, incrémente i (et profites en pour lui donner un vrai nom), et incrémentes le à chaque fichier (puisque visiblement un fichier = un thème).

    Tatayo.
    J'utilise Visual Studio, je suis sur .Net Core en mode console, via Windows.

    Ajouter une fois pour toute? C'est à dire? Comment pourrais-je le faire sans boucler sur les fichiers?

    Désolé, je suis vraiment un débutant, autant j'arrive à faire des algos compliqués quand j'ai déjà vu et répété la chose, autant des choses simples ne me viennent pas à l'esprit car pas l'habitude de les utiliser xD

  6. #6
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2020
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2020
    Messages : 23
    Points : 20
    Points
    20
    Par défaut
    Bon, magnifique, l'idée de renommé "i" dans la boucle et le dissocié du tableau, afin de l'incrémenter sans boucle "for" a fonctionné !

    Voici le résultat :
    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
     
            public static Theme[] ReadFromDirectory(string directoryPath)
            {
                //Comptage des fichiers dans le dossier, pour préparer la dimension du tableau
                var filesCount = (from file in Directory.EnumerateFiles(directoryPath, "*.txt", SearchOption.AllDirectories) select file).Count();
     
                //Variable qui servira de nombre de "cases" que contiendra le tableau. La taille du tableau. Elle est égale au nombre de fichiers.
                int primaryIndex = filesCount;
     
                //Le tableau de type class "Theme".
                Theme[] themes = new Theme[primaryIndex];
     
                //Récupérations des fichiers
                var files = Directory.EnumerateFiles(directoryPath, "*.txt");
     
     
                int numbering = 0;//Variable qui permettera de numéroter les thèmes du quizz par ordre croissant.
                int cycleIndex = 0;
                foreach (var file in files)
                {
                    //Pour chaque fichier, lecture des lignes contenues dans le fichier.
                    var lines = File.ReadAllLines(file);
     
     
                    foreach (var line in lines)
                    {
                        if (line.Contains("thème"))//Pour chaque ligne, séléctionner celles contenant le mot "thème".
                        {
                            int found = line.IndexOf(": ");//Pour chaque ligne contenant le mot "thème", on extrait le nom du thème à cet indice.
                            Theme theme = new Theme(numbering++, line.Substring(found + 2));//Instanciation de la classe lié au theme.
                            themes[cycleIndex++] = theme;//Pour chaque thème extrait, on le stock dans une case du tableau. 
                        }
                        Console.WriteLine($"{numbering}: {line}");//On verifie, visuellement, que le tout marche bien.
                    }
                }
                return themes;//On renvoi les deux thèmes.
            }
    Merci beaucoup Tatayo !

    Je garde le topic ouvert, car je penses que je ne suis pas au bout de mes peines pour cet exercice !

  7. #7
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    896
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 896
    Points : 1 912
    Points
    1 912
    Par défaut
    Tu as un thème par fichier ?

  8. #8
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2020
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2020
    Messages : 23
    Points : 20
    Points
    20
    Par défaut
    Oui le but était de travailler sur plusieurs fichiers

  9. #9
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2020
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2020
    Messages : 23
    Points : 20
    Points
    20
    Par défaut
    Me revoici pour un autre problème.

    J'utilise les délégués et événements pour faire appel à mes questions/réponses, lorsque l'utilisateur fait son choix de thème pour le quiz.

    Cependant, j'ai plusieurs paramètres en entrée du délégué, dont des tableaux !! Or je ne sais pas comment écrire la balise qui pointera vers l'élément auquel je vais abonner les packs de questions/réponses?

    Voici la partie du code en question :

    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
    40
    41
    42
    43
    44
            //Délégué
            public delegate void delgueQuestionsPackHandler(Theme theme, string[] questions, string[] responses);//ICI les paramètres en entrée qui vont me poser problème dans l'écriture de mon événement.
     
            //Les events que je vais utiliser en balise(point d'encrage).
            public event delgueQuestionsPackHandler VideoGames;
            public event delgueQuestionsPackHandler Manga;
     
            public string Name { get; private set; }//on s'en fout
     
            public IEnumerable<Question> Questions { get; set; }//on s'en fout
     
            public Theme()//on s'en fout
            {
     
            }
     
            public void ThemeChoice(string directoryPath)//La fonction pour le choix du thème
            {
                Console.WriteLine("Selectionnez le thème de votre choix :");
     
                string[] theme = ReadFromDirectory(directoryPath);//On appel la méthode sur laquelle j'ai bloqué précédemment et qui m'a fait créer ce topic :)
     
                //Saisie utilisateur.
                string input = Console.ReadLine();
                int.TryParse(input, out int choice);
     
                //Les choix en fonction de la saisie.
                switch (choice)
                {
                    case 1:
                        //Mon premier event, la balise sur laquelle je vais pouvoir abonner la fonction du packs de questions "Jeux Vidéo".
                        VideoGames?.Invoke(this, questions[i], responses[""]); // ICI MON PROBLEME ! Comment on écrit les paramètres entre parenthèse pour les tableaux de string?
                        _ = theme[0];
                        Console.WriteLine($"{_ = theme[0]}");
                        break;
                    case 2:
                        Manga?.Invoke(this);//ICI AUSSI???
                        _ = theme[1];
                        Console.WriteLine($"{_ = theme[1]}");
                        break;
                    default:
                        break;
                }
            }
    Donc voilà, vous l'aurez compris, je n'ai jamais appris ça, ni eu ce cas auparavant, et ne trouve rien sur le net, pour me dire comment je dois écrire "la balise", dans ce cas de figure.

    Je sais que si le délégué avait eu pour paramètres d'entrée de simple string, je n'aurais eu qu'à mettre des guillemets ("") dans l'event, et ça aurait parfaitement marché. Mais là il s'agit d'un tableau de string ! Peut être que .NET ne prévoit pas ça?

    Pouvez-vous m'aider? merci

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 197
    Points : 12 772
    Points
    12 772
    Par défaut
    Bonjour,
    Lors de la définition du délégué, tu indiques qu'il reçoit en paramètre des tableaux de chaines.
    Et lors de l'appel, tu lui passes (à priori) des chaines.
    Il faut modifier l'un ou l'autre, en fonction de ce que tu veux faire (j'avoue que je n'ai pas regardé le reste du code).

    Tatayo.

  11. #11
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2020
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2020
    Messages : 23
    Points : 20
    Points
    20
    Par défaut
    Citation Envoyé par tatayo Voir le message
    Bonjour,
    Lors de la définition du délégué, tu indiques qu'il reçoit en paramètre des tableaux de chaines.
    Et lors de l'appel, tu lui passes (à priori) des chaines.
    Il faut modifier l'un ou l'autre, en fonction de ce que tu veux faire (j'avoue que je n'ai pas regardé le reste du code).

    Tatayo.
    Salut Tatayo !

    En fait je n'ai pas le choix que de passer les tableaux de chaînes en paramètre du délégué, car la fonction que je veux abonner dessus en contient, et que, pour que ça marche, il faut que le délégué soit défini de la même manière que la fonction qui s'y abonne.

    EDIT : Résumé ultime :

    Ma fonction que je veux abonner, ressemble à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public void CallVideoGamesQuestions(Theme theme, string[] questions, string[] responses)
    Par conséquent mon délégué ressemble à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    //Délégué
    public delegate void delgueQuestionsPackHandler(Theme theme, string[] questions, string[] responses);
     
    //Event que je vais utiliser en balise(point d'encrage).
    public event delgueQuestionsPackHandler VideoGames;
    Que dois-je écrire pour les tableaux en paramètre de l'appel? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    VideoGames?.Invoke(this, comment dois-je écrire le paramètre tableau questions ici?, comment dois-je écrire le paramètre tableau reponses ici?);
    Merci mille fois pour ton aide !

  12. #12
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2020
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2020
    Messages : 23
    Points : 20
    Points
    20
    Par défaut
    EUREKA ! J'ai trouvé :p

    Tout seule comme un grand ^^

    Voici le code corrigé :

    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
            public void ThemeChoice(string directoryPath)//La fonction pour le choix du thème
            {
                Console.WriteLine("Selectionnez le thème de votre choix :");
    
                string[] theme = ReadFromDirectory(directoryPath);
    
    
                //Ici les tableaux que je devais appeler et utiliser dans les paramètre de l'appel de l'event :)
                var questions = Question.ReadQuestionsFromDirectory(@"C:\Users\raikh\OneDrive\Bureau\Numérique\Développement Informatique\CSHARP Development\QuizzGame\BDD Quizz\Fichiers Themes");
                var responses = Response.ReadResponsesFromDirectory(@"C:\Users\raikh\OneDrive\Bureau\Numérique\Développement Informatique\CSHARP Development\QuizzGame\BDD Quizz\Fichiers Themes");
    
                //Saisie utilisateur.
                string input = Console.ReadLine();
                int.TryParse(input, out int choice);
    
                //Les choix en fonction de la saisie.
                switch (choice)
                {
                    case 1:
                        //Mon premier event, la balise sur laquelle je vais pouvoir abonner la fonction du packs de questions "Jeux Vidéo".
                        VideoGames?.Invoke(this, questions, responses); // ICI la solution ! Et voilà ! Il me suffisait de reprendre le tableau "questions" et "responses", et les passer en paramètre pour que mon event marche^^ c'est ça que je cherchais ! :p
                        _ = theme[0];
                        Console.WriteLine($"{_ = theme[0]}");
                        break;
                    case 2:
                        Manga?.Invoke(this, questions, responses);//ICI AUSSI
                        _ = theme[1];
                        Console.WriteLine($"{_ = theme[1]}");
                        break;
                    default:
                        break;
                }
            }

  13. #13
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    896
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 896
    Points : 1 912
    Points
    1 912
    Par défaut
    Pourquoi tu utilises un chemin de fichier absolu en dur pour ReadQuestions et ReadResponses alors que tu as déjà un chemin de répertoire en paramètre de ta fonction ?

Discussions similaires

  1. Réponses: 4
    Dernier message: 03/03/2008, 13h30
  2. Réponses: 14
    Dernier message: 01/05/2007, 19h25
  3. Réponses: 1
    Dernier message: 10/09/2006, 16h09
  4. Appel d'une fonction pour renommer un fichier
    Par navis84 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 13/04/2006, 15h13
  5. Détourner une fonction pour copier un fichier en mémoire
    Par Rodrigue dans le forum C++Builder
    Réponses: 6
    Dernier message: 12/11/2003, 08h29

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