Partage
  • Partager sur Facebook
  • Partager sur Twitter

Ouvrir un fichier texte

Récupérer valeurs

    30 décembre 2007 à 21:50:39

    Bonjour,

    Je fait présentement une calculatrice en console (sous Windows XP). Je veux ajouter le logarithme en base 10 et donc j'ai fait d'une table de logarithme dans un ficher texte qui ressemble à ça:

    1,10_____0,0413927
    1,11_____0,0453230
    1,12_____0,0492180
    1,13_____0,0530784
    etc.

    Je ne sais donc pas comment donner la valeur 0,0413927 à y quand par exemple x = 1,10.

    Merci beaucoup!
    • Partager sur Facebook
    • Partager sur Twitter
      30 décembre 2007 à 22:08:52


      Pourquoi as-tu besoin de stocker le log10 dans une table ?

      • Partager sur Facebook
      • Partager sur Twitter
        30 décembre 2007 à 22:12:17

        Je ne suis pas sur de comprendre ta question mais si c'est par rapport au fait qu'il existe déja une fonction log10 dans math.h, c'est juste que je veux faire une calculatrice sans math.h (voir ma signature :p ) et qu'on ne peut pas calculer exactement le logarithme en base 10 d'un nombre décimal, donc il faut une table de logarithmes.

        Merci!
        • Partager sur Facebook
        • Partager sur Twitter
          30 décembre 2007 à 22:28:16

          Autant pour moi, je n'avais pas lu ta signature :D

          J'ai une autre question: Quel est le typage de ta variable x ?
          • Partager sur Facebook
          • Partager sur Twitter
            30 décembre 2007 à 22:31:38

            Le typage de x est double (donc je vais peut-être obligé de rajouter des zéros à toutes les valeurs que peut prendre x dans le fichier mais je verrai! :p )

            J'espere qu'avec cela vous aller pouvoir m'aider!
            • Partager sur Facebook
            • Partager sur Twitter
              30 décembre 2007 à 22:53:46

              Tu as 3 approches possibles :

              1) Tu fais une recherche dans ton fichier a chaque log10 demandé -> Performances compromises par les acces disque.

              2) Tu charges ton fichier dans une table en memoire -> Utilisation memoire importante.

              3) Tu charges une partie de ton fichier dans un tampon lors chaque acces -> performances mediocres, utilisation memoire limitée.

              Le Premiere approche est la plus facile a implementer mais je te la deconseille niveau performance.
              La deuxieme n'est utile que si ta table de log10 n'est pas trop grande ( < 100Mo) et si tu arrives a optimiser les recherches (table de hashage).
              Je pense que la troisieme methode ne te conviendra pas si tu demandes de l'aide dans ce forum.

              A toi de choisir :D
              • Partager sur Facebook
              • Partager sur Twitter
                30 décembre 2007 à 22:58:39

                Salut!

                Je crois que je vais choisir la façon numéro 2 car mon fichier est un fichier texte et il est très loin de prendre plus de 100 Mo :-° (je me demande même s'il va prendre 1 Mo!)

                Cependant, même si je sais charger le fichier, je n'ai aucune idée de ce qu'est une table de hashage :(

                Merci de continuer à m'éclairer!
                • Partager sur Facebook
                • Partager sur Twitter
                  30 décembre 2007 à 23:45:31

                  Bon, puisque ta table de log10 ne changera pas de taille lors d'une execution de ton programme, tu pourras te limiter a un tableau de "double" avec une fonction qui associera DIRECTEMENT un "x" a une case du tableau (ce n'est pas tout a fait le fonctionnement d'une table de hash).

                  1. #include <stdio.h>
                  2. /* On suppose qu'apres la lecture du fichier on a : */
                  3. double min = 1.10;
                  4. double max = 1.13;
                  5. double pas = 0.01;
                  6. double tab[] = {0.0413927, 0.0453230, 0.0492180, 0.0530784};
                  7. /* Fonction qui retourne la case de la table de
                  8.  * log10 associee a une valeur
                  9.  */
                  10. int case (double x)
                  11. {
                  12.   if (x < min || x > max)
                  13.     return -1;
                  14.   return (int) ((x - min) / pas);
                  15. }
                  16. /* Fonction log10 */
                  17. double log10 (double x)
                  18. {
                  19.   int n = case (x);
                  20.   if (n < 0)
                  21.   {
                  22.     fprintf (stderr,"le log10 de %f n'est pas definit\n", x);
                  23.     return 0;
                  24.   }
                  25.   return tab[n];
                  26. }
                  • Partager sur Facebook
                  • Partager sur Twitter
                    30 décembre 2007 à 23:48:22

                    par curiosité: ca compile ?????
                    appeler une fonction "case" (le meme que celui du switch) ^^
                    • Partager sur Facebook
                    • Partager sur Twitter
                      30 décembre 2007 à 23:52:49

                      lol, probablement que non. Je n'ai pas de quoi compiler sous windog pour tester :D

                      Edit: L'essentiel est que ca te donne une idee de comment resoudre ton probleme ;)
                      • Partager sur Facebook
                      • Partager sur Twitter
                        31 décembre 2007 à 1:18:42

                        EDIT : Je vais essayer avec quelque chose dans le même genre!

                        Mais si les nombres sont dans un fichier, je ne peux pas faire un tableau, alors comment je fais?
                        Je commence par charger le fichier et je fais quoi après?

                        Merci beaucoup!
                        • Partager sur Facebook
                        • Partager sur Twitter
                          31 décembre 2007 à 12:55:52

                          En fait quand je parle de charger le fichier, ca veut dire le lire et sauvegarder toutes ses entrees dans une table. Tu peux utiliser la fonction "fscanf" pour ca .
                          • Partager sur Facebook
                          • Partager sur Twitter
                            31 décembre 2007 à 15:46:35

                            Mais heu... Pourquoi ne pas calculer toi-même le logarithme plutôt que d'utiliser des valeurs stockées...?

                            Pour les valeurs inférieures à 25, par exemple, il y a un algorithme assez simple:
                            1. réel loga_neperien (réel nombre)
                            2. {
                            3.                 réel u = 0;
                            4.                 entier compteur = 0;
                            5.                 tant que (compteur <30) faire
                            6.                 {
                            7.                       u = (u - 1.0) + (nombre/ exponentielle(u)) ;
                            8.                       compteur = compteur +1;
                            9.                 }
                            10.                 retourner u;
                            11. }
                            • Partager sur Facebook
                            • Partager sur Twitter
                              31 décembre 2007 à 16:58:33

                              J'utilise une table de logarithme premièrement parce que c'est que le logarithme en base 10 et non népérien, deuxièmemenr parce qu'il est impossible de le calculer exactement le logarithme d'un nombre décimal et une table est à mon avis plus précise car elle tient compte de 6 décimales.

                              Pour le charger, il faut utiliser fopen et fclose? et après j'utilise fscanf?

                              Bref, je vais essayer avec fscanf et je vous tiens au courant! ;)
                              Merci!
                              • Partager sur Facebook
                              • Partager sur Twitter
                                31 décembre 2007 à 17:16:05

                                Le logarithme en base x (quel que soit x, 10 ou autre) s'obtient à l'aide de logarithme népérien, c'est la définition même du log en base x, hein.

                                Je te conseillais cet algo parce que selon moi, une calculatrice doit calculer, et non pas lire, mais bon, tu fais comme tu veux...
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  31 décembre 2007 à 17:32:18

                                  Je t'accorde le point qu'on peut calculer tous les logarithmes en base x grâce au népérien, mais de toute façon, pour calculer le népérien, il faut utiliser soit une table, soit un algorithme qui permet une appoximation, et j'ai décidé d'utiliser la table, mais je peux toujours essayer avec l'algotithme que tu m'a donné.

                                  D'ailleurs je croit que la plupart des calculatrices sont incapables de le calculer, elles utilisent des tables ou un algorithme approximatif à moins que je ne m'abuse (me corriger si je me trompe!)

                                  Je continue et je vous donne des nouvelles!

                                  EDIT : Désolé, mais je ne vois vraiment pas comment utiliser fscanf pour charger le fichier, je suis un peu mélangé, merci de m'aider!
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    31 décembre 2007 à 17:52:25

                                    Si ton fichier comporte les lignes x log(x), tu fais:
                                    1. fsanf(monfichier, "%lf %lf", &val, &log);
                                    pour récupérer les deux valeurs et les stocker dans val et log.
                                    Personnellement, j'utilise d'abord fgets pour récupérer une ligne et ensuite je récupère les valeurs de la ligne avec sscanf.

                                    Tu trouveras plein d'infos sur les fonctions scanf et dérivées ici: http://xrenault.developpez.com/tutoriels/c/scanf/
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      31 décembre 2007 à 19:34:39

                                      J'ai encore un problème!

                                      J'arrive à aller chercher une valeur dans mon fichier mais c'est toujours la premiere valeur! J'essaie de faire une boucle avec le fgetc mais je n'y arrive pas.

                                      Voici mon code (un bout quand meme :p );
                                      1. else if (fichier != NULL)//Pour vérifier que mon fichier ouvre
                                      2.     {
                                      3.         x = 100*x;
                                      4.         x = (long) x; //Ces deux lignes ne sont pas importantes pour le probleme!
                                      5.         for(x; fgetc(fichier) != x || fgetc(fichier) != EOF; fgetc(fichier))//J'ai essayé plein de choses mais ca c encore pire (boucle infinie)
                                      6.         fscanf(fichier, "%lf__%lf", &x, &a);
                                      7.         //...
                                      8.         fclose(fichier);


                                      et mon fichier texte :

                                      110__0.5255
                                      111__0.5256
                                      etc.
                                      Merci de m'indiquer mon erreur!

                                      Toupi : peut-tu m'expliquer comment faire avec fgets si c'est ta méthode? car je n'y arrive pas avec fgetc...
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        2 janvier 2008 à 16:41:39

                                        up! J'ai beau essayé, je n'arrive pas à faire cette boucle!
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          2 janvier 2008 à 17:24:36

                                          1. char ligne[32]; /* En statique, avec une taille qu'on sait être suffisante */
                                          2. FILE *fichier = fopen("fichier.txt", "r");
                                          3. if (fichier != NULL)
                                          4. {
                                          5.    /* Tant qu'on n'est pas à la fin du fichier, on récupère une ligne du fichier */
                                          6.    while (fgets(ligne, sizeof ligne, fichier) != NULL)
                                          7.    {
                                          8.       float val = 0, log = 0;
                                          9.       /* La ligne est forcément de type "val__log" puisque c'est comme ça que tu l'as
                                          10.       écrite. Attention, si ce n'est pas le cas, la fonction sscanf fera n'importe quoi:
                                          11.       le f de sscanf signifie "formaté", donc si c'est pas le bon format, ça
                                          12.       cause de gros problèmes */
                                          13.       sscanf(ligne, "%lf__%lf", &val, &log);
                                          14.       printf("%lf %lf\n", val, log);
                                          15.    }
                                          16. }
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            2 janvier 2008 à 17:33:15

                                            Mais si je comprend bien, ce code affichera toutes les lignes du fichier?

                                            Si oui, comment faire pour que cela affiche seulement la ligne qui contient la valeur voulue?

                                            Par exemple, si l'entrée est 110, on se rend à ligne 110__0.5256 et on n'affiche que cette ligne.

                                            Faut-il ajouter une conditon du genre "|| fgets(ligne, sizeof ligne, fichier) == 'x__y' (par exemple 110 dans l'exemple que j'ai donné plus haut)??
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              2 janvier 2008 à 18:24:47

                                              Oui, ce code lit chaque ligne (dans le while), récupère les deux valeurs et les affiche. C'est juste pour te montrer comme lire correctement ton fichier, après tu te débrouilles avec tes tests, je vais pas tout te faire :)
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                2 janvier 2008 à 18:27:48

                                                Citation : marc3757

                                                Mais si je comprend bien, ce code affichera toutes les lignes du fichier?


                                                Ce code lit surtout le fichier avec ta table (avec le format que tu as specifié). Libre a toi de faire ce que tu veux avec les entrees lues mais l'idee n'etait pas de les stocker dans un tableau ? ^^
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  2 janvier 2008 à 18:35:21

                                                  Ouais merci mais je sais comment le lire et c'est pas comme si j'avais pas essayé :(
                                                  Seulement, lorsque j'avais essayé un code semblable à celui que tu m'a donné (d'ailleurs j'ai essayé le tien et cela donne le même résultat) Cela affiche:
                                                  0.00000 0.00000
                                                  0.00000 0.00000
                                                  etc. :o

                                                  ou un peu n'importe comme chiffre genre 4312523532634.5235 :o

                                                  Et la je suis tout mélangé entre quoi utiliser: fgetc, fgets, sscanf, fscanf, etc. et si ca continue je crois que je vais abandonner de lire ce fichier :colere2:

                                                  Cependant, merci pour votre patience

                                                  Citation : Frava

                                                  Citation : marc3757

                                                  Mais si je comprend bien, ce code affichera toutes les lignes du fichier?


                                                  Ce code lit surtout le fichier avec ta table (avec le format que tu as specifié). Libre a toi de faire ce que tu veux avec les entrees lues mais l'idee n'etait pas de les stocker dans un tableau ? ^^



                                                  En y pensant, je ne sais pas si c'est une meilleure idée cependant comme le fichier contient plus de 2000 chiffres, je crois que cela va aller mieux de lire le fichier et de rechercher dans le fichier au lieu que dans le tableau
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    2 janvier 2008 à 18:44:13

                                                    Si ton tableau est trié, une recherche dichotomique (il y a plus efficace, mais celle-ci est très simple) sera déjà bien plus efficace que de lire ligne par ligne ton fichier ;)
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      2 janvier 2008 à 19:09:42

                                                      Merci pour la réponse qui m'a l'air très intéressante car oui, la première valeur de chaque ligne est triée! Je ne connais pas vraiment les fonctions de recherche dont la dichotomique mais cela doit être assez facile à trouver des informations là-dessus!

                                                      Je cherche, je trouve et je reposte si j'ai des questions!
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        2 janvier 2008 à 20:36:57

                                                        pas besoin de dichotomie si l'intervalle entre tes valeurs de x est constant, tu peux calculer directement (cf. mon exemple de code)
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          2 janvier 2008 à 20:40:59

                                                          Mais pour cela, faut je charge le fichier dans un tableau, non?

                                                          Et je ne vois pas comment vu qu'il y a deux valeurs par lignes et qu'il contient beaucoup beaucoup de lignes :(

                                                          Donc je ne sais toujours pas quel moyen utiliser, je dois encore y réfléchir : utilisation de plus de mémoire ou rapidité ou facilité (pour créer le code :-° )

                                                          Quelqu'un peut m'éclairer sur quoi utiliser parce que là je ne crois pas comprendre si j'utilise la recherche dichotomique, faut-il que les chiffres soient dans un tableau?
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            2 janvier 2008 à 21:04:36

                                                            Citation : marc3757

                                                            Mais pour cela, faut je charge le fichier dans un tableau, non?

                                                            Et je ne vois pas comment vu qu'il y a deux valeurs par lignes et qu'il contient beaucoup beaucoup de lignes :(


                                                            La procedure que t'a donné Toupi affecte le x lu a la variable "val" et le y correspondant (cad le log10 de x) a la variable "log", et cela pour chacune des lignes de ton fichier...

                                                            Citation : marc3757

                                                            Quelqu'un peut m'éclairer sur quoi utiliser parce que là je ne crois pas comprendre si j'utilise la recherche dichotomique, faut-il que les chiffres soient dans un tableau?


                                                            Je crois que tu as deja tous les elements pour faire ton programme, mais je vais quand meme t'expliquer un peu mon code.
                                                            D'apres ce que tu as montré de ton fichier, j'ai retenu que la valeur minimale de x pour laquelle tu definis le log10 etait 1.10, c'est pour ca que j'ai stocké dans la variable "min" cette valeur. De meme j'ai vu que la valeur maximale de x pour laquelle tu difinis le log10 etait 1.13, c'est pour ca que j'ai stocké dans la variable "max" cette valeur. De plus, j'ai remarqué que si je prenait un x au hasard, alors tu definissais le log10 de (x + 0.01) a la ligne suivante, c'est ce que j'ai sauvegardé dans la variable "pas". Mais je vais te laisser comprendre mon code pour le reste :D
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              2 janvier 2008 à 21:08:54

                                                              Merci pour ton explication mais je comprend ton code, mais il faut que je rentre toutes les valeurs dans un tableau, et ca va être très long! (mais si ca continue, ca va être le meilleure alternative :( )

                                                              Mais c'est l'exemple de Toupi que je ne comprenais si cela nécessitais un tableau. Alors que maintenant je vais essayer du coté de la recherche dichotomique si il n'y a pas un moyen plus rapide.
                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              Ouvrir un fichier texte

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown