Partage
  • Partager sur Facebook
  • Partager sur Twitter

[FAIT][Défis] #1 : zMol, la chimie pour tous

Venez vous entraîner !

    8 septembre 2011 à 18:51:51

    Citation : Pouet_forever

    Citation : lucas-84

    @informaticienzero : je ne l'ai pas dit, mais si tu savais le temps que j'ai passé pour mon code tout ridicule... :-°


    C'est bizarre, pour quelqu'un ayant programmé plusieurs mini-OS ça devrait se faire les doigts dans le nez. :-°



    Qu'est-ce que tu fais sur le forum C++ toi ? :p
    Bah oui, un mini-OS c'est faisable, mais j'ai jamais dit l'avoir fait tout seul sans doc'.
    J'avoue avoir mis un peu plus de temps à coder l'exercice que je ne l'avais prévu...

    PS : toujours à passer derrière moi, toi...
    • Partager sur Facebook
    • Partager sur Twitter
    Staff désormais retraité.
      8 septembre 2011 à 19:12:43

      Citation : kaka551

      Il y'a pas des exemples pour tester l'imbrication des accolades ?


      Tu peux partir sur un truc simple. Tu considères que l'entrée utilisateur est correcte (aucune parenthèse manquante etc.).
      Tu fais ta fonction 'evaluer'.
      Pour chaque caractère, tu regardes :
      - Si c'est une majuscule -> c'est une molécule, tu fais ce qu'il faut faire pour savoir s'il y a plusieurs lettres et récupérer la valeur de la molécule;
      - Si c'est un chiffre -> c'est un coefficient, tu récupères le coefficient et tu le multiplies à la molécule trouvée avant;
      - Si c'est une parenthèse ouvrante -> tu appelles la fonction 'evaluer' en positionnant la chaîne sur le caractère suivant (càd le caractère juste après la parenthèse)
      - Si c'est une parenthèse fermante -> tu renvoies la valeur de l'expression trouvée

      En pseudo-code ça pourrait donner ça :

      Pour chaque caractère de la chaîne, faire :
        Si le caractère est une majuscule :
          Récupérer la molécule (et avancer la chaîne) et récupérer la valeur de cette molécule
        Sinon si le caractère est un chiffre :
          Récupérer le chiffre (et avancer la chaîne) et le multiplier à la valeur trouvée avant
        Sinon si c'est une parenthèse ouvrante :
          Positionner la chaîne sur le caractère suivant
          Appeler la fonction 'evaluer' et récupérer ce qu'elle renvoie
        Sinon si c'est une parenthèse fermante :
          Retourner le résultat trouvé précédemment


      lucas-84 >


      C'est pas méchant ce que je te dis hein. :-°
      C'est juste pour souligner que 'mini-OS' ça fait un peu gros.
      • Partager sur Facebook
      • Partager sur Twitter
        8 septembre 2011 à 19:16:41

        Citation : Pouet_forever


        lucas-84 >


        C'est pas méchant ce que je te dis hein. :-°
        C'est juste pour souligner que 'mini-OS' ça fait un peu gros.


        Ouf, j'ai eu peur. On reste amis alors ? :lol:
        • Partager sur Facebook
        • Partager sur Twitter
        Staff désormais retraité.
          8 septembre 2011 à 19:31:55

          @Pouet_forever >> Merci pour l'aide, mais le code je l'ai fini il ne reste plus qu'a essayer si j'ai pas fait des bêtises. je vais faire le niveau 5 et poster le code pour avoir vos avis.
          • Partager sur Facebook
          • Partager sur Twitter
            8 septembre 2011 à 19:34:15

            Citation : lucas-84

            Ouf, j'ai eu peur. On reste amis alors ? :lol:


            Image utilisateur
            • Partager sur Facebook
            • Partager sur Twitter
              9 septembre 2011 à 9:06:03

              Citation : Pouet_forever

              Tu peux partir sur un truc simple. Tu considères que l'entrée utilisateur est correcte (aucune parenthèse manquante etc.).
              Tu fais ta fonction 'evaluer'.
              Pour chaque caractère, tu regardes :
              - Si c'est une majuscule -> c'est une molécule, tu fais ce qu'il faut faire pour savoir s'il y a plusieurs lettres et récupérer la valeur de la molécule;
              - Si c'est un chiffre -> c'est un coefficient, tu récupères le coefficient et tu le multiplies à la molécule trouvée avant;
              - Si c'est une parenthèse ouvrante -> tu appelles la fonction 'evaluer' en positionnant la chaîne sur le caractère suivant (càd le caractère juste après la parenthèse)
              - Si c'est une parenthèse fermante -> tu renvoies la valeur de l'expression trouvée


              Marrant, c'est exactement la description de mon code. ;)

              La faiblesse éventuelle est que les entrée invalides ne sont pas toutes détectées (exemple: 3(O2), O2)3, etc.), mon code par exemple ne gère que les atomes inexistants et les caractères inconnus (genre H2O?)...
              • Partager sur Facebook
              • Partager sur Twitter
                9 septembre 2011 à 11:41:48

                Pour dire vrai j'ai pas regardé ton code. ^^
                Sinon pour éviter l'erreur de parenthèses, tu peux tout simplement garder une variable avec le nombre de parenthèses et si au final elle est différente de 0 c'est que ya un souci. :)
                • Partager sur Facebook
                • Partager sur Twitter
                  9 septembre 2011 à 11:48:43

                  Argh, ça fait déjà une semaine et je n'ai toujours pas posté mon code !

                  Il ne me reste plus qu'un tout petit problème de liste chainée à résoudre (j'en ai déjà résolu 2/3) puis je m'attaquerai vraiment à l'exo en lui-même. :)


                  Edit : Il y a une limite ? :)
                  • Partager sur Facebook
                  • Partager sur Twitter
                    9 septembre 2011 à 13:40:30

                    Citation : Pouet_forever

                    Sinon pour éviter l'erreur de parenthèses, tu peux tout simplement garder une variable avec le nombre de parenthèses et si au final elle est différente de 0 c'est que ya un souci. :)


                    Non, cette methode n'est pas bonne. Exemple : )H2O(.

                    Enfin bon, je n'ai pas dit qu'ajouter cette gestion est spécialement difficile, hein, simplement que ça ne s'inscrit pas forcément naturellement "à l'intérieur" de l'algo proposé (à vrai dire je n'y ai pas trop réfléchi).

                    Citation : paraze

                    Edit : Il y a une limite ? :)


                    La seule limite est ta patience. De toute façon, rien n'est noté, seule la participation compte. ;)
                    • Partager sur Facebook
                    • Partager sur Twitter
                      9 septembre 2011 à 13:47:24

                      @yoch : Je voulais dire si il y a une limite de temps pour poster une réponse.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        9 septembre 2011 à 14:08:31

                        Oui, ma réponse signifie : aucune, tant que le SdZ reste ouvert. ;)
                        • Partager sur Facebook
                        • Partager sur Twitter
                          9 septembre 2011 à 14:48:58

                          Jveux pas dire mais... si on a déjà codé un programme qui calcule ce genre de chose:
                          2 * (4 + 5 * 7) / 4
                          (Et ce genre de programme est plutôt très connu)

                          Alors tout cet exo, le zMol, se résume simplement à de la conversion de chaîne... :D

                          str_replace(ma_chaine, 'He', '4.0026');
                          etc.

                          Parce qu'au final se serait idiot de faire un programme qui ne calcule QUE la masse molaire sans même pouvoir résoudre 2+2.
                          • Partager sur Facebook
                          • Partager sur Twitter
                            9 septembre 2011 à 14:51:48

                            Yoch > non, si tu rencontres une par ouvrante tu incrementes de 1 et si tu rencontres une par fermante tu decrementes. En faisant ca tu es sur d'avoir le bon nom re de parentheses et bien ordonnees. ;)
                            • Partager sur Facebook
                            • Partager sur Twitter
                              9 septembre 2011 à 14:54:27

                              Ce qu'il veut dire c'est qu'il faut EN PLUS de ça rajouter une condition qui renvoie false si ce nombre devient négatif ne serait-ce qu'une fois.

                              Sinon effectivement le truc )( ça passe.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                9 septembre 2011 à 15:04:57

                                Tout a fait, apres tout dépends comme la conception est faite, il y a plusieurs écoles.
                                Ha Standford la méthode engagée aurait été beaucoup plus pointillé.
                                Mais tous ca c'est dû à l'échange des idées en prog...
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  9 septembre 2011 à 17:51:04

                                  Citation : Mr21

                                  Jveux pas dire mais... si on a déjà codé un programme qui calcule ce genre de chose:
                                  2 * (4 + 5 * 7) / 4
                                  (Et ce genre de programme est plutôt très connu)

                                  Alors tout cet exo, le zMol, se résume simplement à de la conversion de chaîne... :D

                                  str_replace(ma_chaine, 'He', '4.0026');
                                  etc.

                                  Parce qu'au final se serait idiot de faire un programme qui ne calcule QUE la masse molaire sans même pouvoir résoudre 2+2.



                                  Ces exos sont pour débutants, et s'adressent principalement à un public qui n'a pas encore forcément réalisé de parser (mais c'est prévu dans la liste de GuilOooo ;) ).
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  Bla bla bla
                                    9 septembre 2011 à 18:02:45

                                    Je poste mon code pour le niveau 5 :
                                    #include <stdio.h>
                                    #include <stdlib.h>
                                    #include <string.h>
                                    
                                    #define MAX_ATOME 5
                                    #define MOLECULE_SIZE 20
                                    #define NOM_FICHIER "atome.txt"
                                    #define ERROR(chaine, var, retour) printf(chaine, var); \
                                                                        return(retour);
                                    
                                    typedef struct
                                    {
                                        char nom[MAX_ATOME];
                                        double massMolaire;
                                    }atom;
                                    
                                    int lire(char *chaine, int longueur)
                                    {
                                        char *positionEntree = NULL;
                                    
                                        if (fgets(chaine, longueur, stdin) != NULL)
                                        {
                                            positionEntree = strchr(chaine, '\n');
                                            if (positionEntree != NULL)
                                            {
                                                *positionEntree = '\0';
                                            }
                                            else
                                            {
                                                viderBuffer();
                                            }
                                            return 1;
                                        }
                                        else
                                        {
                                            viderBuffer();
                                            return 0;
                                        }
                                    }
                                    
                                    int viderBuffer()
                                    {
                                        int c = 0;
                                        while (c != '\n' && c != EOF)
                                        {
                                            c = getchar();
                                        }
                                    }
                                    
                                    atom* chargeAtme(int * nbr_atome)
                                    {
                                        FILE * fichier = NULL;
                                        int i = 0;
                                        char nom[MAX_ATOME] = "\0";
                                        double masse = .0;
                                        atom * Atom;
                                        if(!(fichier = fopen(NOM_FICHIER, "r"))) {ERROR("echec d'ouverture du fichier %s\n",NOM_FICHIER, 1)}
                                        for(;!feof(fichier); (*nbr_atome)++)
                                        fscanf(fichier, "%s %lf\n", nom, &masse);
                                        Atom = malloc((*nbr_atome) * sizeof(atom*));
                                        rewind(fichier);
                                        for(;!feof(fichier);i++)
                                        fscanf(fichier, "%s %lf\n", Atom[i].nom, &Atom[i].massMolaire);
                                        fclose(fichier);
                                        return Atom;
                                    }
                                    
                                    double calculeMasse(atom * Atom, int nbr_atom, char molecule[], char parenthese)
                                    {
                                        int i = 0;
                                        double masse = 0, masse1 = 0;
                                        for(; molecule[i] && molecule[i] != parenthese; i++)
                                        {
                                            char nomAtom[MAX_ATOME] = "\0";
                                            int nbrCarAtome = 1, coef = 1, debutAtom = i;
                                            double masse_sous_molecule = 0;
                                            masse1 = 0;
                                            if(isupper(molecule[i]))
                                            {
                                                for(; (islower(molecule[i+1]) || isdigit(molecule[i+1])) && molecule[i+1] && molecule[i+1] != parenthese; i++)
                                                {
                                                    if(islower(molecule[i+1]))
                                                    nbrCarAtome++;
                                                    else if(isdigit(molecule[i+1]))
                                                    {
                                                        int nbr_num = 1;
                                                        for(; isdigit(molecule[i+1]); i++)
                                                        nbr_num++;
                                                        coef = strtol(molecule + (i - nbr_num + 2), NULL, 10);
                                                        i--;
                                                    }
                                                }
                                            strncpy(nomAtom, molecule + debutAtom, nbrCarAtome);
                                            masse1 = (Atom[cherche(Atom, nomAtom, nbr_atom)].massMolaire * coef);
                                            }
                                            else if(molecule[i] == '(')
                                            {
                                                char sousMolecule[MOLECULE_SIZE] = "\0";
                                                int par = 1;
                                                i++;
                                                strcpy(sousMolecule, molecule + i);
                                                masse_sous_molecule = calculeMasse(Atom, nbr_atom, sousMolecule , ')');
                                                for(; par != 0; i++)
                                                {
                                                    if(molecule[i] == '(')
                                                    par++;
                                                    else if(molecule[i] == ')')
                                                    par--;
                                                }
                                                for(;isdigit(molecule[i]); i++);
                                            i--;
                                            }
                                        masse +=masse1 + masse_sous_molecule;
                                        }
                                        if(molecule[i] == ')' && isdigit(molecule[i+1]))
                                        masse *= strtol(molecule + i + 1, NULL, 10);
                                        return masse;
                                    }
                                    
                                    int cherche(atom * Atom, char nomAtom[], int nbr_atom)
                                    {
                                        int i = 0;
                                        for(;i < nbr_atom; i++)
                                        {
                                            if(!strcmp(nomAtom, Atom[i].nom))
                                            return i;
                                        }
                                        return 0;
                                    }
                                    
                                    int test(char molecule[])
                                    {
                                        int i = 0;
                                        int nbr_par_ferme = 0, nbr_par_ouvre = 0;
                                        for(; molecule[i]; i++)
                                        {
                                            if(!isalnum(molecule[i]) && molecule[i] != '(' && molecule[i] != ')')
                                            printf("Caractere %c invalide\n",molecule[i]);
                                            else if(molecule[i] == '(')
                                            nbr_par_ouvre++;
                                            else if(molecule[i] == ')')
                                            nbr_par_ferme++;
                                        }
                                        if(nbr_par_ferme < nbr_par_ouvre)
                                        printf("Il y'a %d accolade ouvrant de plus\n", nbr_par_ouvre - nbr_par_ferme);
                                        else if(nbr_par_ferme > nbr_par_ouvre)
                                        printf("Il y'a %d accolade fermant de plus\n",nbr_par_ferme - nbr_par_ouvre);
                                    
                                        return 0;
                                    }
                                    
                                    int ajoute(atom * Atom)
                                    {
                                        FILE * fichier = NULL;
                                        char atome[MAX_ATOME] = "\0";
                                        double masse = .0;
                                        char chaine_a_ecrire[20];
                                        if(!(fichier = fopen(NOM_FICHIER, "a+"))) {ERROR("echec d'ouverture du fichier %s\n",NOM_FICHIER,1)}
                                        if(fgets(chaine_a_ecrire, 20, stdin) != NULL)
                                        {
                                            if(sscanf(chaine_a_ecrire, "%2s%*[ ]%lf\n", atome, &masse) == 2)//Pri du code de Taure, donc merci et Désolé de l'avoir recopier
                                            {
                                                if(isupper(atome[0]))
                                                fputs(chaine_a_ecrire, fichier);
                                                else return 1;
                                            }
                                        }
                                        fclose(fichier);
                                        return 0;
                                    }
                                    int main(int argc, char* argv[])
                                    {
                                        char molecule[MOLECULE_SIZE];
                                        int nbr_atome = 0;
                                        char choix[4] = "\0";
                                        atom * Atom = chargeAtme(&nbr_atome);
                                        if(!Atom) return EXIT_FAILURE;
                                        do{
                                            lire(choix, 4);
                                            if(!strcmp(choix, "cal"))
                                            {
                                                puts(">");
                                                if(lire(molecule,MOLECULE_SIZE-1) != 0)
                                                {
                                                    test(molecule);
                                                    printf("La masse molaire de %s est %f g.mol-1\n\n",molecule, calculeMasse(Atom, nbr_atome, molecule, '\0'));
                                                }
                                            }
                                            else if(!strcmp(choix, "add"))
                                            {
                                                puts("<");
                                                if(!ajoute(Atom))
                                                puts("Atom Ajoute\n");
                                                else
                                                puts("Erreur de l'ajout de l'atom");
                                            }
                                        }while(strcmp(choix, "end"));
                                        free(Atom);
                                        return EXIT_SUCCESS;
                                    }
                                    

                                    Pour l'utiliser :

                                    Pour calculer : cal ==> puis entrez le nom du molécule (normalement il gèrent l'imbrication des parenthèse).
                                    Pour ajouter c'est : add puis entrez le nom de l’atome et ca masse molaire séparer d'un espace.
                                    Pour quitter c'est end

                                    Ps : je vais éditer dans une dizaines de minutes pour teste les atomes ajouté :-°
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      9 septembre 2011 à 18:13:10

                                      Citation : _Fender_

                                      Ces exos sont pour débutants, et s'adressent principalement à un public qui n'a pas encore forcément réalisé de parser (mais c'est prévu dans la liste de GuilOooo ;) ).


                                      J'en ai conscience. Mais l'exo aurait pu se résumer à convertir une chaine du genre :
                                      (CH4)2
                                      en :
                                      (12.011 + 1.0079 * 4) * 2

                                      Et pour ceux qui sont sur linux on leur aurait donné :
                                      ./zMol '(CH4)2' | bc
                                      (histoire de voir directement le bon résultat)

                                      parce que là j'ai peur ('fin c'est pas grave mais bon) qu'il y en ai qui fasse tout un parseur pas du tout générique ^^
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        9 septembre 2011 à 18:32:08

                                        @_Fender_ N'oublie pas de m'ajouter a la liste des participants !!
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          9 septembre 2011 à 18:39:50

                                          Citation : Mr21

                                          parce que là j'ai peur ('fin c'est pas grave mais bon) qu'il y en ai qui fasse tout un parseur pas du tout générique ^^



                                          Tu as sans doute raison, mais il y a quand même bien moins de choses à gérer que pour un parser, et ici, on peut très bien faire un calcul "a la volée", plutôt que de convertir toute la chaine. ;)

                                          Citation : kaka551

                                          @_Fender_ N'oublie pas de m'ajouter a la liste des participants !!



                                          Petit détail, ça serait mieux si tu disais "@Exercices C". (La je pense que schadocalex est en train de s'en occuper).
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          Bla bla bla
                                            9 septembre 2011 à 19:03:23

                                            Citation : Mr21

                                            Sinon effectivement le truc )( ça passe.


                                            Si tu suis ce que j'ai mis plus haut, tu n'auras pas ce problème puisque tu reviendras à la fonction appelante sans avoir fini tes parenthèses (ou en trop). :)
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              9 septembre 2011 à 19:08:00

                                              Moi, je dirai qu'il ne faut pas écouter ce que dit Pouet : il n'est pas dans son état normal, 10h de jazz (répétitif) d'affilé, on met du temps à s'en remettre. http://www.youtube.com/watch?v=KHy7DGLTt8g
                                              :lol::lol::lol:


                                              Sinon, je continue petit à petit mon prog.
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                9 septembre 2011 à 23:25:45

                                                Bonjour,

                                                Niveau 4, code un peu (beaucoup ?) bourrin, mais il fait tous les tests de validité de formules avec les parenthèses:
                                                #include <ctype.h>
                                                #include <errno.h>
                                                #include <limits.h>
                                                #include <stdio.h>
                                                #include <stdlib.h>
                                                #include <string.h>
                                                
                                                const char conffile[] = "zmol.conf";
                                                
                                                struct atom {
                                                	char name[5];
                                                	double mass;
                                                } atoms[300];
                                                const int nb_atoms = sizeof atoms / sizeof *atoms;
                                                
                                                
                                                void bad_formula(void) {
                                                	fprintf(stderr, "bad formula\n");
                                                	exit(EXIT_FAILURE);
                                                }
                                                
                                                
                                                void load_atoms(void) {
                                                	int i;
                                                	FILE *const fp = fopen(conffile, "r");
                                                
                                                	if (!fp) {
                                                		fprintf(stderr, "Could not open %s.\n", conffile);
                                                		exit(EXIT_FAILURE);
                                                	}
                                                
                                                	for (i = 0; i < nb_atoms - 1 && fscanf(fp, "%4s %lf", atoms[i].name, &atoms[i].mass) == 2; ++i);
                                                	atoms[i].mass = 0;
                                                	fclose(fp);
                                                }
                                                
                                                
                                                double atom_mass(const char *name, int name_length) {
                                                	int i;
                                                
                                                	for (i = 0; atoms[i].mass != 0 && strncmp(atoms[i].name, name, name_length); ++i);
                                                	return atoms[i].mass;
                                                }
                                                
                                                
                                                const char *read_atom(const char *s) {
                                                	if (isupper(*s))
                                                		++s;
                                                	while (islower(*s))
                                                		++s;
                                                	return s;
                                                }
                                                
                                                
                                                double mass_mol(const char **molecule) {
                                                	const char *after_atom;
                                                	double last_mass = 0, tot_mass = 0;
                                                	
                                                	do {
                                                		if ((after_atom = read_atom(*molecule)) != *molecule) {
                                                			last_mass = atom_mass(*molecule, after_atom - *molecule);
                                                			if (last_mass == 0)
                                                				bad_formula();
                                                			tot_mass += last_mass;
                                                			*molecule = after_atom;
                                                		}
                                                		else if (isdigit(**molecule) && **molecule != '0') {
                                                			char *endptr;
                                                			long n;
                                                
                                                			errno = 0;
                                                			n = strtol(*molecule, &endptr, 10);
                                                			if (tot_mass == 0 || (n == LONG_MAX && errno == ERANGE))
                                                				bad_formula();
                                                			tot_mass += (n - 1) * last_mass;
                                                			*molecule = endptr;
                                                		}
                                                		else if (**molecule == '(') {
                                                			++*molecule;
                                                			tot_mass += last_mass = mass_mol(molecule);
                                                			if (**molecule != ')')
                                                				bad_formula();
                                                			++*molecule;
                                                		}
                                                		else if (**molecule == ')') {
                                                			if (tot_mass == 0)
                                                				bad_formula();
                                                			return tot_mass;
                                                		}
                                                		else if (**molecule != '\0')
                                                			bad_formula();
                                                	} while (**molecule != '\0');
                                                
                                                	return tot_mass;
                                                }
                                                
                                                
                                                int main(int argc, char **argv) {
                                                	const char *molecule;
                                                	double mass;
                                                
                                                	if (argc != 2) {
                                                		fprintf(stderr, "usage: %s molecule\n", argv[0]);
                                                		exit(EXIT_FAILURE);
                                                	}
                                                
                                                	load_atoms();
                                                
                                                	molecule = argv[1];
                                                	mass = mass_mol(&molecule);
                                                	if (*molecule != '\0')
                                                		bad_formula();
                                                	printf("La masse molaire de cette molécule est %f g.mol-1.\n", mass);
                                                	return 0;
                                                }
                                                

                                                A ce propos, quelqu'un d'autre a-t-il fait un code qui détecte des formules fausses genre "(", "C(O", "CO)", "2C", etc. ?

                                                Édit : petit embellissement du code
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  9 septembre 2011 à 23:56:34

                                                  Normalement mon code gère toutes les possibilités d'erreurs et affiche ce qui va pas. :)
                                                  J'aime bien cette ligne-là tot_mass += last_mass = mass_mol(molecule); :lol:
                                                  Par contre, tu ne peux pas comparer les doubles comme ça if (last_mass == 0) :)

                                                  Edit: Mon code avec les expressions que tu as données :

                                                  >>> (
                                                  Erreur de syntaxe: Parenthèse fermante manquante.
                                                  >>> C(O
                                                  Erreur de syntaxe: Parenthèse fermante manquante.
                                                  >>> CO)
                                                  Erreur de syntaxe: Parenthèse ouvrante manquante.
                                                  >>> 2C
                                                  Coefficient non précédé d'une molécule.
                                                  >>> ()
                                                  Erreur de syntaxe:  Epression manquante dans entre les parenthèses.

                                                  D'ailleurs, je viens de voir qu'il y a une chose que je gère pas, c'est le (). :-°
                                                  Je corrige de suite. :)

                                                  Fix'd. :)
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    10 septembre 2011 à 1:10:25

                                                    Marc Mongenet, bizarre ton gros bloc là, c'est flexible toussa?

                                                    J'ai l'impression que c'est du code qui fait une chose et une seule et si ensuite tu veux mettre une option en plus faut tout revoir...

                                                    Une énorme fonction qui gère la vie et l'univers c'est pas hyper cool à ce qu'il paraît.

                                                    'fin on s'en fiche c'est pas un projet en soit tu vas m'dire mais bon, bravo quand même ^^

                                                    Comme à dit la personne au dessus:
                                                    les doubles ne se testent pas vraiment comme ça mais c'est encore plus flagrant dans ta fonction atom_mass()!
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      10 septembre 2011 à 2:27:02

                                                      Citation : Pouet_forever

                                                      Par contre, tu ne peux pas comparer les doubles comme ça if (last_mass == 0) :)


                                                      Ben dans ce cas ça va, car 0 est le flag d'erreur de la fonction atom_mass. Je ne teste pas le résultat d'une addition ou autre opération.

                                                      Plus concrètement:
                                                      double x = 0;
                                                      if (!(x == 0))
                                                           exit(1); /* on n'arrive jamais là, n'est-ce pas? */
                                                      


                                                      @Mr21: Nan, c'est pas un exemple de joli code à prendre pour s'inspirer.
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        10 septembre 2011 à 10:27:34

                                                        (Bon, puisqu'il faut râler)

                                                        Pourquoi ne pas couper les lignes qui dépassent les 80 caractères ? ^^
                                                        C'est embêtant sur le sdz en plus, on est obligé de scroller et c'est pas très agréable...
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                        Staff désormais retraité.
                                                          10 septembre 2011 à 11:25:52

                                                          Bonjour,

                                                          Une participation en C99(juste pour pouvoir déclarer des variables n'importe où) qui utilise des globales en plus...

                                                          #include <stdio.h>
                                                          #include <stdlib.h>
                                                          #include <string.h>
                                                          #include <ctype.h>
                                                          #include <errno.h>
                                                          
                                                          #define PATH            "data.txt"
                                                          #define ATOMS_INIT_SIZE 16
                                                          
                                                          enum
                                                          {
                                                              E_OK,
                                                              E_ALLOC,
                                                              E_FILE,
                                                              E_ATOM,
                                                              E_OBR,
                                                              E_CBR,
                                                              E_NUM
                                                          };
                                                          
                                                          
                                                          char const *s_err[] =
                                                          {
                                                              "",
                                                              "Bad alloc !...",
                                                              "Could not open file !",
                                                              "Unknown atom !",
                                                              ") expected",
                                                              ") whithout ("
                                                          };
                                                          
                                                          typedef struct
                                                          {
                                                              char name[3];
                                                              double mass;
                                                          } Atom;
                                                          
                                                          /* Globales ------------------------------------------------------------------*/
                                                          size_t g_nAtoms;
                                                          Atom *g_atoms;
                                                          
                                                          
                                                          
                                                          void clearBuf(void)
                                                          {
                                                              int c;
                                                              while((c = getchar()) != '\n');
                                                          }
                                                          
                                                          
                                                          
                                                          int cmp(void const *pa, void const *pb)
                                                          {
                                                              Atom a = *(Atom *)pa;
                                                              Atom b = *(Atom *)pb;
                                                          
                                                              return strcmp(a.name, b.name);
                                                          }
                                                          
                                                          
                                                          void skipSpaces(void)
                                                          {
                                                              int c;
                                                              while(isblank(c = getchar()))
                                                                  ;
                                                              ungetc(c, stdin);
                                                          }
                                                          
                                                          
                                                          
                                                          char *readAtomName(char *buf)
                                                          {
                                                              char *p_buf = buf;
                                                              int c = getchar();
                                                          
                                                              *p_buf++ = c;
                                                              c = getchar();
                                                              if(islower(c))
                                                              {
                                                                  *p_buf++ = c;
                                                              }
                                                              else
                                                              {
                                                                  ungetc(c, stdin);
                                                              }
                                                              *p_buf = '\0';
                                                          
                                                              return buf;
                                                          }
                                                          
                                                          
                                                          unsigned readFactor(void)
                                                          {
                                                              unsigned ret = 1;
                                                              int c = getchar();
                                                          
                                                              if(isdigit(c))
                                                              {
                                                                  ret = c - '0';
                                                                  while(isdigit(c = getchar()))
                                                                  {
                                                                      ret *= 10;
                                                                      ret += c - '0';
                                                                  }
                                                              }
                                                          
                                                              ungetc(c, stdin);
                                                              return ret;
                                                          }
                                                          
                                                          
                                                          
                                                          double evalWorker(int *err)
                                                          {
                                                              double ret = 0.;
                                                              char name[3];
                                                              int c;
                                                          
                                                              while((c = getchar()) != '\n')
                                                              {
                                                                  double crtMass = 0;
                                                                  skipSpaces();
                                                                  if(c == '(')
                                                                  {
                                                                      crtMass += evalWorker(err);
                                                                      if((c = getchar()) != ')')
                                                                      {
                                                                          *err = E_OBR;
                                                                          ungetc(c, stdin);
                                                                      }
                                                                  }
                                                                  else if (c == ')')
                                                                  {
                                                                      ungetc(c, stdin);
                                                                      return ret;
                                                                  }
                                                                  else
                                                                  {
                                                                      ungetc(c, stdin);
                                                                      Atom *crtAtom = bsearch(readAtomName(name),
                                                                                              g_atoms, g_nAtoms, sizeof *crtAtom, cmp);
                                                                      if(crtAtom == NULL)
                                                                      {
                                                                          *err = E_ATOM;
                                                                      }
                                                                      else
                                                                      {
                                                                          crtMass = crtAtom->mass;
                                                                      }
                                                                  }
                                                                  skipSpaces();
                                                                  ret += crtMass * readFactor();
                                                              }
                                                          
                                                              ungetc(c, stdin);
                                                              return ret;
                                                          }
                                                          
                                                          
                                                          double eval(int *err)
                                                          {
                                                              double ret = evalWorker(err);
                                                              if(getchar() != '\n')
                                                              {
                                                                  *err = E_CBR;
                                                                  clearBuf();
                                                              }
                                                              return ret;
                                                          }
                                                          
                                                          
                                                          void init(int *err)
                                                          {
                                                              FILE *in = fopen(PATH, "r");
                                                              if(in == NULL)
                                                                  *err = E_FILE;
                                                              else
                                                              {
                                                                  size_t capacity = ATOMS_INIT_SIZE;
                                                                  g_atoms = malloc(capacity * sizeof *g_atoms);
                                                                  if(g_atoms == NULL)
                                                                  {
                                                                      *err = E_ALLOC;
                                                                  }
                                                          
                                                                  while(*err == E_OK && fscanf(in, "%2s %lf",
                                                                                               g_atoms[g_nAtoms].name,
                                                                                               &g_atoms[g_nAtoms].mass) == 2)
                                                                  {
                                                                      if(g_nAtoms++ == capacity - 1)
                                                                      {
                                                                          capacity *= 2;
                                                                          Atom *tmp = realloc(g_atoms, capacity);
                                                                          if(tmp == NULL)
                                                                          {
                                                                              *err = E_ALLOC;
                                                                          }
                                                                          else
                                                                          {
                                                                              g_atoms = tmp;
                                                                          }
                                                                      }
                                                                  }
                                                                  fclose(in);
                                                          
                                                                  qsort(g_atoms, g_nAtoms, sizeof *g_atoms, cmp);
                                                              }
                                                          }
                                                          
                                                          
                                                          
                                                          int main(void)
                                                          {
                                                              int err = E_OK;
                                                              extern int errno;
                                                          
                                                              init(&err);
                                                              if (err)
                                                              {
                                                                  fprintf(stderr, "%s\n%s\n", s_err[err], strerror(errno));
                                                              }
                                                              else
                                                              {
                                                                  for(;;)
                                                                  {
                                                                      printf("Entrez une molecule \n>>> ");
                                                          
                                                                      int c;
                                                                      if((c = getchar()) == EOF)
                                                                      {
                                                                          break;
                                                                      }
                                                          
                                                                      ungetc(c, stdin);
                                                                      err = E_OK;
                                                          
                                                                      double res = eval(&err);
                                                                      if(err != E_OK)
                                                                      {
                                                                          printf("%s\n", s_err[err]);
                                                                      }
                                                                      else
                                                                      {
                                                                          printf("%f g.mol-1\n", res);
                                                                      }
                                                                  }
                                                              }
                                                          
                                                              free(g_atoms), g_atoms = NULL;
                                                          
                                                              return 0;
                                                          }
                                                          
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                          Zeste de Savoir, le site qui en a dans le citron !

                                                          [FAIT][Défis] #1 : zMol, la chimie pour tous

                                                          × 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