Partage
  • Partager sur Facebook
  • Partager sur Twitter

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

Venez vous entraîner !

    10 septembre 2011 à 12:31:57

    Salut !

    Alors, comme informaticienzero, je poste mon code niveau 2 :
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    
    /*Liste chainee*/
    typedef struct Atome
    {
        char nom[3];
        float val;
        struct Atome *suiv;
    } Atome;
    
    /*Calcule la masse atomique d'un atome*/
    float calcul_masse(Atome *liste, char *s)
    {
        Atome *tmp = liste;
        float masse = 0.0;
    
        if(liste->suiv != NULL)
        {
            while(tmp != NULL)
            {
                if(strcmp(s, tmp->nom) == 0) /*Si l'atome s est egal a l'un des atomes de la liste*/
                {
                    masse = tmp->val;
                    break; /*On quitte la boucle*/
                }
    
                tmp = tmp->suiv;
            }
        }
    
        printf("\t%s = %f\n", tmp->nom, masse);
    
        return masse;
    }
    
    /*Calcule la masse moleculaire d'une modecule*/
    float masse_moleculaire(Atome *liste, char mol[])
    {
        float masse = 0.0;
        int i = 0;
        int t = strlen(mol);
        char tmp[3] = ""; /*Atome actuel*/
    
        printf("\nLa masse moleculaire actuelle --> %f\n", masse);
    
        while(i <= t)
        {
            if((isupper(mol[i])) != 0) /*Si c'est un atome*/
            {
                tmp[0] = mol[i]; /*tmp prend la premiere lettre du nom de l'atome*/
    
                if(i < t && islower(mol[i+1]) != 0) /*Si le caractere suivant est en minuscule (= atome a plusieurs lettres)*/
                {
                    tmp[1] = mol[i+1]; /*tmp se complete avec la deusieme lettre de l'atome*/
                    i++;
                }
    
                masse += calcul_masse(liste, tmp); /*On met a jour la masse actuelle*/
                printf("La masse moleculaire apres l'ajout de la valeur ci-dessus --> %f\n\n", masse);
    
            }
    
            sprintf(tmp, " "); /*On reinitialise tmp (l'atome actuel)*/
    
            i++;
        }
    
        return masse;
    }
    
    /*Affiche la liste*/
    void afficher_liste(Atome *liste)
    {
        Atome *tmp = liste;
    
        if(liste->suiv != NULL)
        {
            while(tmp != NULL)
            {
                printf("%s %f\n", tmp->nom, tmp->val);
                tmp = tmp->suiv;
            }
        }
    }
    
    /*Ajoute un atome dans la liste*/
    Atome *ajout(Atome *liste, char nom[], float val)
    {
        Atome *tmp = malloc(sizeof(Atome));
    
        if(tmp  == NULL)
        {
            exit(EXIT_FAILURE);
        }
    
        /*On copie les attributs mis en argument dans la liste*/
        sprintf(tmp->nom, nom);
        tmp->val = val;
        tmp->suiv = liste;
    
        return tmp; /*On renvoie le nouvel atome*/
    }
    
    /*Renvoie la liste d'atome qu'il y a dans le fichier*/
    Atome *liste_atomes(FILE *fichier)
    {
        Atome *liste = NULL;
        float val = 0;
        char nom[3] = "";
    
        while(nom[0] != '~') /*Si on est pas a la fin du fichier*/
        {
            fscanf(fichier, "%02s %f", nom, &val); /*On copie les attributs de l'atome actuel qui se trouve dans le fichier*/
            if(nom[0] != '~') /*Si on est pas a la fin du fichier, on ajoute l'atome actuel dans la liste*/
                liste = ajout(liste, nom, val);
        }
    
        return liste;
    }
    
    int main(void)
    {
        FILE *fichier = NULL;
        Atome *liste = NULL;
        char mol[100] = "";
    
        if((fichier = fopen("atomes.txt", "r")) == NULL)
            exit(EXIT_FAILURE);
    
        liste = liste_atomes(fichier);
    
        /*Affiche la liste des atomes connus*/
        afficher_liste(liste);
    
        printf("\n>>> ");
        scanf("%s", mol);
        printf("\nLa masse molaire de cette molecule est %f g.mol-1\n\n\n", masse_moleculaire(liste, mol));
    
        fclose(fichier);
    
        return EXIT_SUCCESS;
    }
    

    Aucun warning sous GCC avec une bonne douzaine d'option de compilation. :D

    Un petit exemple d’exécution :
    Na 22.989000
    Cl 35.452999
    Li 6.941000
    He 4.002600
    H 1.007900
    O 15.999000
    C 12.011000
    
    >>> HeOCCClOb
    
    La masse moleculaire actuelle --> 0.000000
    
            He = 4.002600
    La masse moleculaire apres l'ajout de la valeur ci-dessus --> 4.002600
    
            O = 15.999000
    La masse moleculaire apres l'ajout de la valeur ci-dessus --> 20.001600
    
            C = 12.011000
    La masse moleculaire apres l'ajout de la valeur ci-dessus --> 32.012600
    
            C = 12.011000
    La masse moleculaire apres l'ajout de la valeur ci-dessus --> 44.023600
    
            Cl = 35.452999
    La masse moleculaire apres l'ajout de la valeur ci-dessus --> 79.476597
    
             Aucun atome 'Ob' n'a ete trouve, masse = 0.0
    La masse moleculaire apres l'ajout de la valeur ci-dessus --> 79.476593
    
    
    La masse molaire de cette molecule est 79.476593 g.mol-1


    J'espère avoir fait un boulot relativement correct. ^^

    Je m'attaquerai au level 3 un peu plus tard dans la journée.
    • Partager sur Facebook
    • Partager sur Twitter
      10 septembre 2011 à 19:47:31

      Bonsoir !

      Voici enfin mon code. Et pour une fois, en français. :)


      Étant donné qu'il s'agit d'une syntaxe linéaire, je me suis contenté d'une lecture en place de la formule entrée, sans traitement préalable.
      Pour la lecture du fichier, je charge toutes les infos dans un grand tableau statique et sans les trier, c'est plus simple. J'aurais sans doute pu faire plus performant avec un tri alphabétique par exemple, mais je ne me suis pas fatigué. :-°

      PS: Pour la bonne cause, je me suis amusé à recoder une fonction de lecture de fichier avec allocation dynamique de mémoire (j'aurais bien utilisé scanf("%as") mais c'est une extension GNU).


      Je pense encore l'améliorer, notamment au niveau de la lecture du nom d'un atome de la formule et de la recherche de sa masse (deux fonctions séparées actuellement, je pense pouvoir faire directement la recherche avec une comparaison en place plutôt que de recopier le nom d'abord).

      Je suis allé jusqu'au niveau 4.
      Pour les parenthèses, je gère les imbrications infinies simplement avec de la récursivité.
      Je ne vois pas trop l'intérêt du niveau 5 (avec scanf et fprintf, c'est fait en moins de deux), d'autant plus que ça compliquerait "l'interface utilisateur".
      En revanche, je pense pouvoir mettre en place facilement l'affichage du détail des calculs (avec un petit bonus dont j'ai idée mais qui me pose des problèmes conceptuels).

      Je n'ai pas fait beaucoup de tests, mais ça a l'air de fonctionner normalement pour chaque cas de figure (une parenthèse en trop, manquante, un atome inconnu…).


      Excusez la présentation et les commentaires absents ou pas clairs, c'est fait à la va-vite. :honte:

      #include <stdio.h>
      #include <ctype.h>
      #include <string.h>
      #include <stdlib.h>
      
      
      typedef struct Atome {
      	double masseMol;
      	char nom[3];
      } Atome;
      
      
      
      /* vérifie que le nom de l'atome est valide (au plus les 2 premiers caractères) */
      int nomAtomeValide(const char* nom) {
      	return  isupper(nom[0])  &&  (!nom[1] || islower(nom[1]));
      }
      
      
      
      /* lit le fichier et en extrait les informations, qu'on enregistre dans le
         tableau de structures `Atome` pointé (contenant `nbTab` éléments aux maximum) ;
         renvoie le nombre d'atomes lus */
      size_t chargerInfos(FILE* f, Atome tabInfos[], size_t nbTab) {
      	size_t i =  0;
      	int r =  2;
      	
      	rewind(f);
      	while(r!=EOF && i<nbTab) {
      		r =  fscanf(f, "%2s %lf\n",
      		  tabInfos[i].nom,
      		  &tabInfos[i].masseMol);
      		if(r!=EOF  &&  !nomAtomeValide(tabInfos[i].nom))
      			fprintf(stderr, "erreur dans le fichier d'informations :"
      			  " nom d'atome invalide : '%s'\n", tabInfos[i].nom);
      		else if(r==1)
      			fputs("erreur dans le fichier d'informations :"
      			  " saisie invalider : il manque la masse molaire\n",
      			  stderr);
      		else
      			++i;
      	}
      	
      	return i-1;
      }
      
      
      
      /* écrit le nom d'atome se trouvant au début de la chaîne `formule`.
         Retourne l'adresse du 1er caractère non-lu. */
      void lireNomAtome(const char** formule, char* nom) {
      	if(isupper(**formule)) {
      		*nom++ =  *(*formule)++;
      		if(islower(**formule))
      			*nom++ =  *(*formule)++;
      	}
      	*nom =  '\0';
      }
      
      
      
      /* renvoie la masse molaire de l'atome du nom spécifié */
      double masseMolAtome(const char* nom, const Atome tabInfos[], size_t nbTab) {
      	size_t i;
      	for(i=0; i<nbTab; ++i)
      		if(strcmp(nom, tabInfos[i].nom) == 0)
      			return tabInfos[i].masseMol;
      	fprintf(stderr, "erreur : atome inconnu : '%s'\n", nom);
      	return 0.0;
      }
      
      
      
      /* calcule la masse molaire de la molécule dont la formule est passée en
         argument (sous la forme d'un pointeur sur un pointeur sur char). S'arrête au
         caractère spécifié ; retourne le résultat et met le pointeur `*formule` sur
         le dernier caractère lu. */
      double calculerMasseMol(const char** formule, char cFin,
                              const Atome tabInfos[], size_t nbTab) {
      	double r =  0,
      	       masseMol,
      	       coeff;
      	char nomLu[3];
      	
      	while(1) {
      		if(**formule=='(') {
      			++*formule;
      			masseMol =  calculerMasseMol(formule, ')',
      			  tabInfos, nbTab);
      			r +=  masseMol;
      			if(**formule)    ++*formule;
      		}
      		else if(**formule == cFin)
      			return r;
      		else if(**formule==')' || **formule=='\0') {
      			fputs("erreur : fin ou parenthèse fermante inattendue\n",
      			  stderr);
      			return r;
      		}
      		else if(isdigit(**formule)) {
      			coeff =  (double)atoi(*formule);
      			r +=  (coeff-1)*masseMol;
      			while(isdigit(**formule))    ++*formule;
      		}
      		else if(isupper(**formule)/*nomAtomeValide(*formule)*/) {
      			lireNomAtome(formule, nomLu);
      			masseMol =  masseMolAtome(nomLu, tabInfos, nbTab);
      			r +=  masseMol;
      		}
      		else {
      			fprintf(stderr, "erreur : saisie invalide à partir"
      			  " d'ici : `%s`\n", *formule);
      			return r;
      		}
      	}
      }
      
      
      
      
      
      /* écrit toute la ligne du fichier ('\n' exclus) dans un buffer dynamique et
         renvoie ce buffer */
      char* lireLigneFichier(FILE* f) {
      	char *s, *p;
      	int c;
      	size_t size =  0,
      	       capac =  32;
      	
      	s =  malloc(capac*sizeof(char));
      	if(s==NULL)    exit(EXIT_FAILURE);
      	
      	while((c=fgetc(f)) != '\n'  &&  c!=EOF) {
      		s[size] = c;
      		++size;
      		if(size >= capac) {
      			capac *=  2;
      			p =  realloc(s, capac*sizeof(char));
      			if(p==NULL) {
      				free(s);
      				return NULL;
      			}
      			s =  p;
      		}
      	}
      	s[size] =  '\0';
      	p =  realloc(s, (size+1)*sizeof(char));
      	if(p==NULL) {
      		free(s);
      		return NULL;
      	}
      	
      	return p;
      }
      
      
      
      int main(int argc, char** argv) {
      	FILE* f;
      	Atome tabInfos[118];   // il y a jusqu'à 118 atomes dans la classification périodique
      	char* formule;
      	const char* p;
      	double res =  0;
      	size_t nbTab;
      	
      	f= fopen("mol.inf", "r+");
      	if(f==NULL) {
      		fputs("erreur : échec à l'ouverture du fichier"
      		  " d'informations.\n", stderr);
      		return EXIT_FAILURE;
      	}
      	
      	nbTab =  chargerInfos(f, tabInfos, sizeof(tabInfos)/sizeof(*tabInfos));
      	
      	if(argc==1) {
      		fputs("Entrez une molécule :\n>>> ", stdout);
      		//scanf("%as", &formule);
      		formule =  lireLigneFichier(stdin);
      	} else
      		formule =  argv[1];
      	//printf("formule entrée : %s\n", formule);
      	
      	p =  formule;
      	res =  calculerMasseMol(&p, 0, tabInfos, nbTab);
      	printf("masse molaire moléculaire : %f g.mol-1\n", res);
      	
      	
      	
      	if(argc==1)    free(formule);
      	fclose(f);
      	
      	return EXIT_SUCCESS;
      }
      


      En effet, 200 lignes n'étaient pas de trop… Je me tairais la prochaine fois (je n'ai aucun « compas dans l'œil »).
      • Partager sur Facebook
      • Partager sur Twitter
        11 septembre 2011 à 13:33:17

        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 ;) ).


        Oui. Surtout que ici, à moins de demander une gestion d'erreurs complète, l'évaluation est notablement plus simple.

        Concernant la gestion des erreurs, on peut assez facilement gérer les parenthèses (Pouet à proposé une methode, j'en propose une différente ci-dessous, il me semble que d'autres aussi en ont mis), mais je ne crois pas que ce soit si facile de gérer tous les types d'erreurs, il va falloir définir une grammaire à un moment, et il ne semble pas que ce soit le but de l'exo. Exemple, supposons que ceci soit une erreur (je pense que ça devrait l’être) : O2 5, il faut encore surcharger le code pour gérer ça, etc. A terme, ce n'est pas viable, il me semble.

        Code modifié pour la gestion des parenthèses (j'aime pas trop) :
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        #include <ctype.h>
        
        #define filename        "Atomes.txt"
        #define ATOM_NAME_SZ    8
        #define INPUT_SZ        80
        
        typedef struct
        {
            char nom[ATOM_NAME_SZ];
            double masse;
        } Atome;
        
        typedef struct _ls
        {
            Atome at;
            struct _ls* next;
        } Lst_Atomes;
        
        typedef struct
        {
            size_t size;
            Atome* array;
        } Tab_Atomes;
        
        
        /* fonction de comparaison, pour trier les atomes par noms */
        static int cmp (const void* a, const void *b)
        {
            return strcmp ( ((Atome*)a)->nom, ((Atome*)b)->nom );
        }
        
        /* fonction qui charge le fichier à l'aide d'une liste chainée,
        puis passe le tout dans un tableau,
        et retourne le tableau trié par nom */
        Tab_Atomes chargement_fichier (void)
        {
            FILE* infile = NULL;
            Lst_Atomes* lst = NULL;
            size_t sz = 0;
        
            /* charge le contenu du tableau dans une liste chainee */
            if ( (infile = fopen(filename, "r")) != NULL )
            {
                Atome a;
                while ( fscanf(infile, "%s %lf\n", a.nom, &a.masse) == 2 )
                {
                    Lst_Atomes* nelem = malloc(sizeof *nelem);
                    nelem->at = a, nelem->next = lst, lst = nelem;
                    ++sz;
                }
        
                fclose(infile);
            }
        
            /* initialise le tableau */
            Tab_Atomes tab;
            tab.size = sz;
            tab.array = malloc(sz * sizeof(Atome));
        
            /* on remplit le tableau et on free la liste en meme temps */
            size_t i;
            for (i=0; i<tab.size; ++i)
            {
                tab.array[i] = lst->at;
                Lst_Atomes* tmp = lst;
                lst = lst->next, free(tmp), tmp = NULL;
            }
        
            /* on trie les atomes par noms, pour utiliser bsearch ulterieurement */
            qsort(tab.array, sz, sizeof *(tab.array), cmp);
        
            return tab;
        }
        
        /* fonction qui effectue le parsing de l'expression,
        et calcule la masse molaire à la volée */
        double _eval (char** pinput, Tab_Atomes liste_atomes)
        {
            double retval = 0, current = 0;
            while (**pinput)
            {
                char name[ATOM_NAME_SZ] = "";
                if (isalpha(**pinput))  /* Atome */
                {
                    retval += current;
        
                    char* start = *pinput;
                    size_t sz = 1;
                    while ( islower(*++*pinput) )  /* avance tant qu'on trouve des lettres minuscules */
                        ++sz;
                    strncpy(name, start, sz);
        
                    Atome* at = bsearch(name, liste_atomes.array, liste_atomes.size, sizeof(Atome), cmp);
                    if (at == NULL)  /* si l'atome correspondant n'est pas trouvé dans le tableau - erreur */
                    {
                        fprintf(stderr, "Atome inconnu '%s': arret.\n", name);
                        exit(1);
                    }
                    current = at->masse;
                }
                else if (isdigit(**pinput))  /* Quantite */
                {
                    char* end;
                    unsigned factor = strtoul(*pinput, &end, 10);
                    *pinput = end;
                    current *= factor;
                }
                else if (**pinput == '(')
                {
                    ++*pinput;
                    retval += current;
                    current = _eval(pinput, liste_atomes);  /* on fait un appel recursif */
                    if (**pinput == ')')
                    {
                        ++*pinput;
                        break;
                    }
                    else
                    {
                        fprintf(stderr, "Erreur : parenthses fermante attendue.\n");
                        exit(1);
                    }
                }
                else if (isspace(**pinput))
                {
                    ++*pinput;
                }
                else  /* Entrée non reconnue  */
                {
                    break;
                }
            }
        
            return retval + current;
        }
        
        double eval (char* input, Tab_Atomes liste_atomes)
        {
            double ret = _eval(&input, liste_atomes);
            if (*input != '\0')  /* si toute la chaine n'a pas pu etre évaluée */
            {
                fprintf(stderr, "Entree inattendue : arret.\n");
                exit(1);
            }
            return ret;
        }
        
        int main()
        {
            Tab_Atomes liste_atomes = chargement_fichier();
        
            char input[INPUT_SZ];
            while (1)
            {
                printf( "Entrez une molecule : \n--> " );
                if ( fgets(input, INPUT_SZ, stdin) != NULL )
                {
                    printf("\nLa masse molaire de cette molecule est %lf g.mol-1\n\n", eval(input, liste_atomes));
                }
            }
        
            free(liste_atomes.array);
        
            return 0;
        }
        
        • Partager sur Facebook
        • Partager sur Twitter
          11 septembre 2011 à 15:58:59

          Citation : Yoch

          O2 5, il faut encore surcharger le code pour gérer ça, etc. A terme, ce n'est pas viable, il me semble.

          Mais, suffit de se faire une fonction qui te dit dès le début si ta chaîne est correct ou pas.
          Cette fonction fera appel à une autre fonction qui elle seule regardera si tout est bien parenthésé.
          Et ainsi de suite.
          Pour ton cas: O2 5 bah faut faire une autre fonction qui regarde si avant chaque digit on ne trouve pas un espace puis c'est fini.

          Le code qui calcul ne doit pas constamment vérifier si la chaîne est correct.
          • Partager sur Facebook
          • Partager sur Twitter
            11 septembre 2011 à 20:12:48

            Citation : Mr21

            Mais, suffit de se faire une fonction qui te dit dès le début si ta chaîne est correct ou pas.
            Cette fonction fera appel à une autre fonction qui elle seule regardera si tout est bien parenthésé.
            Et ainsi de suite.
            Pour ton cas: O2 5 bah faut faire une autre fonction qui regarde si avant chaque digit on ne trouve pas un espace puis c'est fini.


            OK, mais c'est ce que j'appelle du bricolage. Même si ça tient ici, l'approche reste globalement mauvaise.

            Citation : Mr21

            Le code qui calcul ne doit pas constamment vérifier si la chaîne est correct.


            Une fois que tu as défini une grammaire, tu as le choix entre séparer les étapes (plus propre), ou mettre tout ensemble (plus fun).
            • Partager sur Facebook
            • Partager sur Twitter
              12 septembre 2011 à 8:57:02

              Bonjour ;)

              Merci aux organisateurs pour l'exercice.

              Je viens soumettre ma solution pour le niveau quatre. La molécule et le nom (ou chemin) du fichier sont transmis dans les paramètres de main. Je verrais comment modifier/améliorer mon code plus tard. Pour le moment, je me suis contenter aux tests de l'énoncé.

              Le code:
              #include <stdio.h>
              #include <stdlib.h>
              #include <string.h>
              #include <ctype.h>
              
              /* Unité de la masse molaire moléculaire. */
              const char unite[] = "g.mol-1";
              
              struct Atome
              {
                 char    nom[3];     /* le nom de l'atome */
                 float   masse;      /* sa masse */
                 int     occurence;  /* le nombre d'occurence (ou coefficient) 
                                        dans une molecule */
              };
              
              typedef struct Atome Atome;
              
              
              /* Déterminer le nombre d'atomes dans une molécule. 
               * - paramètre: la molécule.
               *
               * Retourne le nombre d'atomes.
              **/
              size_t    nombre_atomes(const char*);
              
              
              /* Analyser la molécule en la séparant en différents
               * atomes qui la constituent.
               * 
               * - paramètre 1: la molécule;
               * - paramètre 2: le tableau qui va contenir les différents atomes;
               * - paramètre 3: la taille du tableau.
              **/
              void      analyser(const char*, Atome*, size_t);
              
              
              /* Obtenir la masse d'un atome.
               * - paramètre 1: le nom de l'atome;
               * - paramètre 2: le nom (ou chemin) du fichier dans 
               *                lequel se trouve les atomes.
               *
               * Retourne la masse de l'atome.
              **/
              float     valeur_masse(const char*, const char*);
              
              
              /* Calculer la masse molaire moléculaire.
               * - paramètre 1: tableau des atomes constituant la molécule;
               * - paramètre 2: la taille de ce tableau.
               *
               * Retourne la masse de la molécule.
              **/
              float     masse_molaire(Atome*, size_t, int);
              
              
              /* Déterminer la valeur du coefficient. 
               * - paramètre 1: la molécule à traiter;
               * - paramètre 2: le tableau qui contiendra les atomes;
               * - paramètre 3: la taille du tableau.
               *
               * Retourne la valeur du coefficient.
              **/
              int       traite(const char*, Atome*, size_t);
              
              
              /* Vérifier si une phrase est bien parenthésée.
               * - paramètre: la phrase à traiter.
               *
               * Retourne: 0 si oui et 1 si non.
              **/
              int       zbrace(const char*);
              
              
              /* (But de la fonction ici)
               * - paramètre 1: la molécule à traiter;
               * - paramètre 2: le nom du fichier dans lequel 
               *                se trouve les atomes.
               */
              void      zmol(const char*, const char*);
              
              
              int main(int argc, char * argv[])
              {
                 if(argc >= 3){
                    zmol(argv[1], argv[2]);
                 }
                 else{
                    printf("\n***** Trop peu d'arguments reçus *****\n\n");
                    exit(EXIT_FAILURE);
                 }
                 
                 return EXIT_SUCCESS;
              }
              
              
              void zmol(const char * molecule, const char * fichier)
              {
                 Atome * atomes = NULL;
                 size_t   i, n;
                 float    masse, temp;
                 int      coeff;
                 
                 n = nombre_atomes(molecule);
                 
                 atomes = malloc(n * sizeof(*atomes));
                 
                 if(atomes == NULL){
                    printf("\nErreur d'allocation du tableau d'atomes !\n");
                    exit(EXIT_FAILURE);
                 }
                 
                 coeff = traite(molecule, atomes, n);
                 
                 for(i = 0; i < n; i++){
                    temp = valeur_masse(atomes[i].nom, fichier);
                    if(temp)
                       atomes[i].masse = temp;
                    else{
                       printf("\nL'atome %s n'est pas dans le fichier !\n", atomes[i].nom);
                       exit(EXIT_FAILURE);
                    }
                 }
                 
                 masse = masse_molaire(atomes, n, coeff);
                 
                 printf("\nLa masse molaire du %s est: %.3f %s\n", molecule, masse, unite);
              
                 free(atomes);
              }
              
              
              void analyse(const char * molecule, Atome * atomes, size_t n)
              {
                 size_t i, j, k, l;
              
                 for(i = j = 0; i < strlen(molecule) && j < n; i++){
                    if(isupper(molecule[i])){
                       if(islower(molecule[i + 1])){
                          strncpy(atomes[j].nom, &molecule[i], 2);
                          
                          if(isdigit(molecule[i + 2]))
                             atomes[j].occurence = atoi(&molecule[i + 2]);
                          else
                             atomes[j].occurence = 1;
                       }
                       else if(isdigit(molecule[i + 1])){
                          strncpy(atomes[j].nom, &molecule[i], 1);
                          atomes[j].occurence = atoi(&molecule[i + 1]);
                       }
                       else{
                          strncpy(atomes[j].nom, &molecule[i], 1);
                          atomes[j].occurence = 1;
                       }
                       j++;
                    }
                 }
              }
              
              
              float masse_molaire(Atome * atomes, size_t n, int coeff)
              {
                 size_t i;
                 float masse = 0.0;
              
                 for(i = 0; i < n; i++)
                    masse += atomes[i].masse * atomes[i].occurence;
              
                 return masse * coeff;
              }
              
              
              size_t nombre_atomes(const char * molecule)
              {
                 size_t i, n = 0;
              
                 for(i = 0; i < strlen(molecule); i++){
                    if(isupper(molecule[i]))
                       n++;
                 }
              
                 return n;
              }
              
              
              float valeur_masse(const char * atomeAChercher,
                                 const char * nomFichier)
              {
                 FILE * fichier = NULL;
                 char atome[3];
                 float masse;
              
                 fichier = fopen(nomFichier, "r");
                 
                 if(fichier == NULL){
                    printf("\nErreur d'ouverture du fichier !\n");
                    exit(EXIT_FAILURE);
                 }
                 else{
                    while(fscanf(fichier, "%s %f", atome, &masse) != EOF){
                       if(strcmp(atome, atomeAChercher) == 0){
                          fclose(fichier);
                          return masse;
                       }
                    }
                    fclose(fichier);
                    return 0;
                 }
              }
              
              int traite(const char * mol, Atome * atomes, size_t n)
              {
                 size_t i;
                 char * p_ouverte = NULL;
                 char * p_fermee = NULL;
                 int coeff = 1;
                 
                 if(zbrace(mol) == 0){
                    p_ouverte = strchr(mol, '(');
                    
                    if(p_ouverte == NULL)
                       analyse(mol, atomes, n);
                    else{
                       p_fermee = strchr(mol, ')');
                       
                       if(isdigit(mol[p_fermee - mol + 1])){
                          coeff = atoi(&mol[p_fermee - mol + 1]);
                          analyse(++mol, atomes, n);
                       }
                       else
                          analyse(++mol, atomes, n);
                    }
                 }
                 else{
                    printf("\nExpression mal parenthesee ! \n");
                    exit(EXIT_FAILURE);
                 }
                 return coeff;
              }
              
              
              int zbrace(const char * str)
              {
                 int i;
                 int p_ouverte, p_fermee; /* pour parenthèses ouvertes 
                                             et fermées */
              
                 for(i = 0; str[i] != '\0' && str[i] != '(' && str[i] != ')'; i++)
                    ;
              
                 p_ouverte = p_fermee = 0;
              
                 if(str[i] == ')')
                    return -1;
                 else{
                    for(; str[i] != '\0'; i++){
                       if(str[i] == '(')
                          p_ouverte++;
                       else if(str[i] == ')')
                          p_fermee++;
                    }
                    return p_ouverte - p_fermee;
                 }
              }
              


              En attendant vos remarques/critiques pour l'amélioration du code, merci :)
              • Partager sur Facebook
              • Partager sur Twitter
                13 septembre 2011 à 14:31:50

                Citation : Lebrian

                int zbrace(const char * str)
                {
                   int i;
                   int p_ouverte, p_fermee; /* pour parenthèses ouvertes 
                                               et fermées */
                
                   for(i = 0; str[i] != '\0' && str[i] != '(' && str[i] != ')'; i++)
                      ;
                
                   p_ouverte = p_fermee = 0;
                
                   if(str[i] == ')')
                      return -1;
                   else{
                      for(; str[i] != '\0'; i++){
                         if(str[i] == '(')
                            p_ouverte++;
                         else if(str[i] == ')')
                            p_fermee++;
                      }
                      return p_ouverte - p_fermee;
                   }
                }
                

                Si c'est pour vérifier si une chaîne est bien parenthésée en général, ta fonction n'est pas vraiment parfaite :) :
                printf("%d\n", zbrace("(CH4)2)("));
                

                0
                • Partager sur Facebook
                • Partager sur Twitter
                  13 septembre 2011 à 19:45:23

                  Oups, je modifierai !

                  Merci ;)
                  • Partager sur Facebook
                  • Partager sur Twitter
                    7 octobre 2011 à 21:54:12

                    Bonsoir,

                    Mon code, pour le niveau 4 :

                    /***************************************\
                    *                                       *
                    *                  ZMOL                 *
                    *                                       *
                    *  Logiciel de calcul de masse molaire  *
                    *                                       *
                    *  Prend en entrée la formule d'une     *
                    *  molécule, puis donne en sortie la    *
                    *  masse molaire de cette dernière      *
                    *                                       *
                    \***************************************/
                    
                    
                    #include <stdio.h>
                    #include <stdlib.h>
                    #include <ctype.h>
                    #include <string.h>
                    #include <math.h>
                    
                    #define F_ATOMS "atoms.conf"
                    #define MAX_SIZE 100
                    
                    #define MAX_CHAR 3 
                    
                    /* Element de liste d'atomes. Contient en données : le nom et la
                       masse.
                    */
                    typedef struct atom atom;
                    struct atom {
                        char name[MAX_CHAR];
                        double mass;
                        atom * nxt;
                    };
                    typedef atom* alist_t;
                    
                    
                    /*--------------------------------------------*/
                    alist_t alist_free(alist_t list) {
                    
                        atom * tmp = list;
                        atom * tmpnxt; 
                    
                        while(tmp->nxt != NULL) {
                    	tmpnxt = tmp->nxt;
                    	free(tmp);
                    	tmp = tmpnxt;
                        }
                    
                        return NULL;
                    
                    }
                    
                    alist_t alist_add(alist_t list, char * name, double mass) {
                        
                        atom * newElement = malloc(sizeof(atom));
                        
                        if(strlen(name) <= MAX_CHAR)
                            strcpy(newElement->name, name);
                        else {
                    	free(newElement);
                            return list;
                        }
                    
                        newElement->mass = mass;
                        newElement->nxt = list;
                    
                        return newElement;
                    
                    }
                    
                    alist_t alist_search(alist_t list, char * name) {
                    
                        atom * tmp = list;
                    
                        do {
                    	if(strcmp(name, tmp->name) == 0)
                    	    return tmp;
                    	tmp = tmp->nxt;
                        } while(tmp != NULL); 
                    
                        return NULL;
                    
                    }
                    
                    alist_t cpAtoms(FILE * file, alist_t list) {
                    
                        char atom[MAX_CHAR] = "";
                        double mass = 0;
                    
                        while(fscanf(file, "%s %lf", atom, &mass) == 2) {
                    	list = alist_add(list, atom, mass);
                        }
                    
                        return list;
                    
                    }
                    
                    double getAtomMass(char * atom, alist_t list) {
                    
                        alist_t a = NULL;
                    
                        a = alist_search(list, atom);
                        if(a == NULL)
                    	/*Atome non trouvé...*/
                    	return 0;
                        else
                    	return a->mass;
                    	 
                    }
                    
                    int readAtom(char * atom, char * string, int * i, int end) {
                    
                        if(isupper(string[*i])) {
                    	atom[0] = string[*i];
                    	if(*i <= end)
                    	    *i = *i + 1;
                    	else {
                    	    atom[1] = '\0';
                    	    return 1;
                    	}
                    
                    	if(isupper(string[*i])) {
                    	    atom[1] = '\0';
                    	    return 1;
                    	}
                    	else if(islower(string[*i])) {
                    	    atom[1] = string[*i];
                    	    if(*i <= end)
                    		*i = *i + 1;
                    
                    	    if(isupper(string[*i])) {
                    		atom[2] = '\0';
                    		return 1;
                    	    }
                    	    else if(islower(string[*i])) {
                    		atom[3] = string[*i];
                    		atom[4] = '\0';
                    		return 1;
                    	    }
                    	}
                    
                    	return 1;
                        }
                        else
                    	return 0;
                    
                    }
                    
                    int readNumber(char * string, long int * n, int * i) {
                    
                        *n = strtol((string + *i), NULL, 10);
                        if(*n > 0) {
                    	*i = *i + log10(*n)+1;
                    	return 1;
                        }
                        else
                        	return 0;
                    
                    }
                    
                    double calcMass(char * string, alist_t atomList) {
                    
                        char atom[MAX_CHAR] = "";
                        double totalMass = 0;
                        double tmpMass = 0;
                        long int coeff = 0;
                        static int position = 0;
                        int len = 0;
                    
                        len = strlen(string);
                    
                        do {
                    
                    	/*Si on lit une parenthèse, on rappelle la même 
                    	  fonction pour cette fois lire seulement ce 
                    	  qu'il y a dans la parenthèse*/
                    	if(string[position] == '(') {
                    	    totalMass += tmpMass;
                    	    tmpMass = 0;
                    	    position++;
                    	    tmpMass += calcMass(string, atomList);
                    	    position++;
                    	}
                    
                    	/*Si on lit un coefficient*/
                    	if(readNumber(string, &coeff, &position) == 1 
                    	&& tmpMass != 0) {
                    	    tmpMass *= coeff;
                    	    coeff = 0;
                    	}
                    
                    	totalMass += tmpMass;
                    	tmpMass = 0;
                    
                    	/*Si on lit un atome*/
                    	if(readAtom(atom, string, &position, len) == 1) {
                    	    tmpMass += getAtomMass(atom, atomList);
                    	    while(readAtom(atom, string, &position, len) == 1) {
                    		totalMass += tmpMass;
                    		tmpMass = 0;
                    		tmpMass += getAtomMass(atom, atomList);
                    	    }
                    
                    	}
                    
                    	/*Si l'on arrive pas à lire un atome après un
                    	  coefficient ou une parenthèse...*/
                    	else {
                    	    if(totalMass == 0) {
                    		position = 0;
                    		return 0;
                    	    }
                    	    else
                    		break;
                    	}
                    
                        } while(position <= len || string[position] != ')'); 
                    
                        if(position >= len)
                    	position = 0;
                        totalMass += tmpMass;
                    
                        return totalMass;
                    
                    }
                    
                    void prompt(alist_t atomList) {
                    
                        int running = 1;
                        double result = 0;
                        char string[MAX_SIZE] = "";
                        char * entry = NULL;
                    
                        do {
                    	fputs("Entrez la formule d'une molécule\n > ", stdout);
                    	fgets(string, MAX_SIZE, stdin);
                    	
                            entry = strchr(string, '\n');
                    	if(entry != NULL)
                    	    *entry = '\0';
                    	else
                    	    break;
                            if(strcmp(string, "quit") == 0)
                    	    break;
                    	    
                    	result = calcMass(string, atomList);
                    	if(result > 0)
                    	    printf("Masse molaire calculée : %lf g.mol-1\n\n", result);
                    	else
                    	    fputs("\nUne erreur s'est produite. Soit la syntaxe de la molécule est mauvaise, soit un des atomes n'existe pas, soit le fichier de configuration n'est pas bien écrit.\n\n", stdout);
                    
                        } while(running);
                    
                    }
                    
                    int main(void) {
                        
                        FILE * file = NULL;
                        alist_t atomList = NULL;
                    
                        // Copie des données du fichier dans des variables
                        file = fopen(F_ATOMS, "r");
                        if(file == NULL)
                    	exit(EXIT_FAILURE);
                    
                        atomList = cpAtoms(file, atomList);
                        fclose(file);
                    
                        prompt(atomList);
                    
                        atomList = alist_free(atomList);
                    
                        return EXIT_SUCCESS;
                    
                    }
                    
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Anonyme
                      24 octobre 2011 à 21:08:21

                      Ça y est, après une longue absence, j'ai réussi à résoudre mon problème, mon code gère un coeff infini. :D

                      EDIT : le code est ici.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        24 octobre 2011 à 21:10:15

                        :lol: Bravo à toi \o/

                        (tu entends quoi par coeff infini? met un exemple)
                        • Partager sur Facebook
                        • Partager sur Twitter
                        Anonyme
                          24 octobre 2011 à 21:11:38

                          Citation : Mr21

                          :lol: Bravo à toi \o/

                          (tu entends quoi par coeff infini? met un exemple)



                          Merci. ^^

                          En fait avant, je pouvais pas faire :

                          H15


                          par exemple ; mais maintenant je peux :

                          Donnez la molecule :
                          : H12
                          
                          Voici la masse molaire de H12 : 12.094800 g/mol
                          • Partager sur Facebook
                          • Partager sur Twitter
                            24 octobre 2011 à 21:12:56

                            @informatitienzero: Ah ...
                            Sinon, le coup de la conversion en TI-BASIC, c'est pas si bête :-°
                            • Partager sur Facebook
                            • Partager sur Twitter

                            🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles  - ♡ Copying is an act of love.

                            Anonyme
                              24 octobre 2011 à 21:15:37

                              Citation : @che

                              @informatitienzero: Ah ...
                              Sinon, le coup de la conversion en TI-BASIC, c'est pas si bête :-°



                              C'est à demi inutile : les valeurs sont toujours données, et il faut expliquer ses calculs ; cependant ça peut être utile, pour aller plus vite.

                              Par contre je sais pas gérer les chaines de caractères avec le TI-BASIC. :honte:
                              • Partager sur Facebook
                              • Partager sur Twitter
                                24 octobre 2011 à 22:13:45

                                En TI-BASIC c'est encore plus simple qu'en C (si tu choisis la solution facile) : le parser est intégré de base. Il suffit juste de donner les bonnes valeurs aux variables :

                                1->H
                                12->C
                                etc...


                                - A demander une chaine sous une forme légèrement différente... (exemple : )

                                C+O+(C+H2+O+H)2


                                - Et à l'évaluer l'expression.


                                Input Chaîne1       // Demande à rentrer une chaine (Chaîne1, ou Str1 en Anglais, se trouve en appuyant sur 'Var' -> '7' (sur TI-82))
                                
                                expr(Chaîne1)->R    // La fonction expr évalue la chaine. On stocke le résultat dans R.
                                
                                Disp R



                                Après si tu veux conserver le format d'entrée en respectant la norme d'affichage des molécules, effectivement c'est plus dur. ;)

                                Edit : Et aussi ça peut poser problème pour les molécules à plusieurs caractères.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                Bla bla bla
                                Anonyme
                                  24 octobre 2011 à 22:24:25

                                  Tiens j'avais pas pensé à cette méthode d'initialisation.

                                  Après ça coute rien de le faire à la main aussi. ^^
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    24 octobre 2011 à 22:31:36

                                    Citation : informaticienzero

                                    Après ça coute rien de le faire à la main aussi. ^^

                                    J'avoue, surtout que on doit l'écrire sur la copie ...
                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles  - ♡ Copying is an act of love.

                                      31 octobre 2011 à 18:44:52

                                      On peut encore participer ? :)
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        31 octobre 2011 à 18:49:03

                                        Bien sûr, personne ne va t'interdire de faire des exercices ! ;) Surtout lorsqu'ils sont intéressants.
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          31 octobre 2011 à 18:51:35

                                          Merci ;) ca va me permettre de reviser mon cours de l'année derniere :D:D
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            31 octobre 2011 à 23:48:55

                                            Un petit code non commenté et non optimisé vite fait :
                                            (je décompose le fichier juste pour permettre davantage de lisibilité)
                                            Déclarations :

                                            #include <stdio.h>
                                            #include <stdlib.h>
                                            
                                            #define MAX 256
                                            
                                            #define FICHIER "mol.conf"
                                            
                                            typedef struct
                                            {
                                            	char symbole[3];
                                            	double masse_molaire;
                                            } Atome;
                                            
                                            typedef struct
                                            {
                                            	int size;
                                            	Atome t[MAX];
                                            } CPE;
                                            
                                            int addAtome(CPE * cpe,char const * s);
                                            int findAtome(CPE * cpe, char const s[3]);
                                            double getMasseMolaire(CPE * cpe, int n);
                                            double sumMolecule(CPE * cpe, char * s);
                                            int ajouterAtome(CPE * cpe, char * s);
                                            void afficher(char * s, int deb, int fin);
                                            


                                            main

                                            int main(void)
                                            {
                                            	CPE cpe;
                                            	char buf[1024];
                                            	FILE *in = NULL;
                                            	int i;
                                            	cpe.size = 0;
                                            	in = fopen(FICHIER,"r");
                                            	if(in != NULL)
                                            	{
                                            		while(fgets(buf,1024,in))
                                            			addAtome(&cpe,buf);
                                            		fclose(in);
                                            	}
                                            	printf("Atomes connus :\n");
                                            	for(i = 0;i<cpe.size;i++)
                                            		printf("%s %lf\n",cpe.t[i].symbole,cpe.t[i].masse_molaire);
                                            	printf("> ");
                                            	while(gets(buf))
                                            	{
                                            		double masse;
                                            		if(strcmp(buf,"\n") == 0)
                                            			continue;
                                            		if(strcmp(buf,"exit") == 0)
                                            			break;
                                            		masse = sumMolecule(&cpe,buf);
                                            		if(masse >= 0)
                                            		{
                                            			printf("%s : %f g/mol\n",buf,masse);
                                            		}
                                            		printf("> ");
                                            	}
                                            	return 0;
                                            }
                                            


                                            addAtome

                                            int addAtome(CPE * cpe,char const * s)
                                            {
                                            	if(cpe->size < MAX)
                                            	{
                                            		static int nb_lignes = 1;
                                            		int tmp = sscanf(s,"%s %lf",&(cpe->t[cpe->size].symbole),&(cpe->t[cpe->size].masse_molaire));
                                            		if(tmp < 2)
                                            		{
                                            			fprintf(stderr,"Erreur ligne %d\n",nb_lignes);
                                            			return -1;
                                            		}
                                            		cpe->size++;
                                            		nb_lignes++;
                                            	}
                                            	else
                                            	{
                                            		fprintf(stderr,"Trop d'atomes\n");
                                            		return -1;
                                            	}
                                            	return cpe->size-1;
                                            }
                                            


                                            findAtome

                                            int findAtome(CPE * cpe, char const s[3])
                                            {
                                            	int i = 0;
                                            	for(i = 0;i<cpe->size;i++)
                                            	{
                                            		if(strcmp(s,(cpe->t[i]).symbole) == 0)
                                            			return i;
                                            	}
                                            	if(i == cpe->size)
                                            		return -1;
                                            }
                                            


                                            getMasseMolaire

                                            double getMasseMolaire(CPE * cpe, int n)
                                            {
                                            	return (cpe->t[n]).masse_molaire;
                                            }
                                            


                                            _sumMolecule

                                            double _sumMolecule(CPE * cpe, char * s, int* i)
                                            {
                                            	double somme = 0;
                                            	double somme_tmp = 0;
                                            	int nb_entites = 0;
                                            	int continuer = 1;
                                            	char atome[3];
                                            	int ind_lettre = 0;
                                            	int parenthese = 0;
                                            	int const deb = *i;
                                            
                                            	while(continuer > 0)
                                            	{
                                            		switch(s[*i])
                                            		{
                                            			case '\n':
                                            				s[*i] = '\0';
                                            			case ')':
                                            			case '\0':
                                            				continuer = 0;
                                            				break;
                                            			case '(':
                                            				if(parenthese == 1)
                                            				{
                                            					parenthese = 0;
                                            					if(nb_entites == 0)
                                            					{
                                            						somme += somme_tmp;
                                            						afficher(s,deb,*i);
                                            						printf(" : %f g/mol\n",somme);
                                            					}
                                            					else
                                            					{
                                            						somme += somme_tmp * nb_entites;
                                            						afficher(s,deb,*i);
                                            						printf(" : %f g/mol\n",somme);
                                            						nb_entites = 0;
                                            					}
                                            				}
                                            				else if(ind_lettre != 0)
                                            				{
                                            					atome[ind_lettre] = '\0';
                                            					int ind = findAtome(cpe,atome);
                                            					if(ind < 0)
                                            					{
                                            						fprintf(stderr,"%s non reconnu\n",atome);
                                            						if((ind = ajouterAtome(cpe,atome)) == -1)
                                            							return -1.0;
                                            					}
                                            					if(nb_entites == 0)
                                            					{
                                            						somme += getMasseMolaire(cpe,ind);
                                            						afficher(s,deb,*i);
                                            						printf(" : %f g/mol\n",somme);
                                            					}
                                            					else
                                            					{
                                            						somme += getMasseMolaire(cpe,ind) * nb_entites;
                                            						afficher(s,deb,*i);
                                            						printf(" : %f g/mol\n",somme);
                                            						nb_entites = 0;
                                            					}
                                            				}
                                            				++(*i);
                                            				somme_tmp = _sumMolecule(cpe,s,i);
                                            				if(somme_tmp < 0.0)
                                            					return -1.0;
                                            				parenthese = 1;
                                            				break;
                                            			case '0':
                                            			case '1':
                                            			case '2':
                                            			case '3':
                                            			case '4':
                                            			case '5':
                                            			case '6':
                                            			case '7':
                                            			case '8':
                                            			case '9':
                                            				nb_entites = nb_entites * 10 + (s[*i] - '0');
                                            			case ' ':
                                            			case '\t':
                                            				++(*i);
                                            				break;
                                            			default: //lettre
                                            				if(parenthese == 1)
                                            				{
                                            					parenthese = 0;
                                            					if(nb_entites == 0)
                                            					{
                                            						somme += somme_tmp;
                                            						afficher(s,deb,*i);
                                            						printf(" : %f g/mol\n",somme);
                                            					}
                                            					else
                                            					{
                                            						somme += somme_tmp * nb_entites;
                                            						afficher(s,deb,*i);
                                            						printf(" : %f g/mol\n",somme);
                                            						nb_entites = 0;
                                            					}
                                            				}
                                            				else if((s[*i] & 0x20) == 0) // majuscule
                                            				{
                                            					atome[ind_lettre] = '\0';
                                            					if(ind_lettre != 0)
                                            					{
                                            						int ind = findAtome(cpe,atome);
                                            						if(ind < 0)
                                            						{
                                            							fprintf(stderr,"%s non reconnu\n",atome);
                                            							if((ind = ajouterAtome(cpe,atome)) == -1)
                                            								return -1.0;
                                            						}
                                            						if(nb_entites == 0)
                                            						{
                                            							somme += getMasseMolaire(cpe,ind);
                                            							afficher(s,deb,*i);
                                            							printf(" : %f g/mol\n",somme);
                                            						}
                                            						else
                                            						{
                                            							somme += getMasseMolaire(cpe,ind) * nb_entites;
                                            							afficher(s,deb,*i);
                                            							printf(" : %f g/mol\n",somme);
                                            							nb_entites = 0;
                                            						}
                                            					}
                                            					atome[0] = s[*i];
                                            					ind_lettre = 1;
                                            				}
                                            				else
                                            				{
                                            					atome[ind_lettre] = s[*i];
                                            					++ind_lettre;
                                            				}
                                            				++(*i);
                                            				break;
                                            		}
                                            	}
                                            	if(parenthese == 1)
                                            	{
                                            		parenthese = 0;
                                            		if(nb_entites == 0)
                                            		{
                                            			somme += somme_tmp;
                                            			if(s[*i] != '\0')
                                            			{
                                            				afficher(s,deb,*i);
                                            				printf(" : %f g/mol\n",somme);
                                            			}
                                            		}
                                            		else
                                            		{
                                            			somme += somme_tmp * nb_entites;
                                            			if(s[*i] != '\0')
                                            			{
                                            				afficher(s,deb,*i);
                                            				printf(" : %f g/mol\n",somme);
                                            			}
                                            			nb_entites = 0;
                                            		}
                                            	}
                                            	else
                                            	{
                                            		atome[ind_lettre] = '\0';
                                            		if(ind_lettre != 0)
                                            		{
                                            			int ind = findAtome(cpe,atome);
                                            			if(ind < 0)
                                            			{
                                            				fprintf(stderr,"%s non reconnu\n",atome);
                                            				if((ind = ajouterAtome(cpe,atome)) == -1)
                                            					return -1.0;
                                            			}
                                            			if(nb_entites == 0)
                                            			{
                                            				somme += getMasseMolaire(cpe,ind);
                                            				if(s[*i] != '\0')
                                            				{
                                            					afficher(s,deb,*i);
                                            					printf(" : %f g/mol\n",somme);
                                            				}
                                            			}
                                            			else
                                            			{
                                            				somme += getMasseMolaire(cpe,ind) * nb_entites;
                                            				if(s[*i] != '\0')
                                            				{
                                            					afficher(s,deb,*i);
                                            					printf(" : %f g/mol\n",somme);
                                            				}
                                            				nb_entites = 0;
                                            			}
                                            		}
                                            		else
                                            		{
                                            			int ind = findAtome(cpe,atome);
                                            			if(ind < 0)
                                            			{
                                            				fprintf(stderr,"%s non reconnu\n",atome);
                                            				if((ind = ajouterAtome(cpe,atome)) == -1)
                                            					return -1.0;
                                            			}
                                            			if(nb_entites == 0)
                                            			{
                                            				somme += getMasseMolaire(cpe,ind);
                                            				if(s[*i] != '\0')
                                            				{
                                            					afficher(s,deb,*i);
                                            					printf(" : %f g/mol\n",somme);
                                            				}
                                            			}
                                            			else
                                            			{
                                            				somme += getMasseMolaire(cpe,ind) * nb_entites;
                                            				if(s[*i] != '\0')
                                            				{
                                            					afficher(s,deb,*i);
                                            					printf(" : %f g/mol\n",somme);
                                            				}
                                            				nb_entites = 0;
                                            			}
                                            		}
                                            		atome[0] = s[*i];
                                            		ind_lettre = 1;
                                            	}
                                            	if(s[*i] != '\0')
                                            		++(*i);
                                            	return somme;
                                            }
                                            


                                            sumMolecule

                                            double sumMolecule(CPE * cpe, char * s)
                                            {
                                            	int i = 0;
                                            	return _sumMolecule(cpe,s,&i);
                                            }
                                            


                                            ajouterAtome

                                            int ajouterAtome(CPE * cpe, char * s)
                                            {
                                            	int c,c2;
                                            	double masse;
                                            	char tmp[512];
                                            	FILE* out;
                                            	int ind;
                                            	printf("Souhaitez-vous ajouter l'atome %s ?\n",s);
                                            	while((c = getchar()) != '0' && c != '1' && (c & 0xdf) != 'Y' && (c & 0xdf) != 'O' && (c & 0xdf) != 'N' && c != EOF);
                                            	while((c2 = getchar()) != '\n' && c2 != EOF);
                                            	if((c & 0xdf) == 'Y' || (c & 0xdf) == 'O' || c == '1')
                                            	{
                                            		printf("Masse molaire ?\n");
                                            		if(scanf("%lf",&masse) < 1)
                                            		{
                                            			while((c2 = getchar()) != '\n' && c2 != EOF);
                                            			return -1;
                                            		}
                                            		while((c2 = getchar()) != '\n' && c2 != EOF);
                                            		sprintf(tmp,"%s %f\n",s,masse);
                                            		ind = addAtome(cpe,tmp);
                                            		if(ind < 0)
                                            			return -1;
                                            		out = fopen(FICHIER,"a");
                                            		if(out == NULL)
                                            		{
                                            			fprintf(stderr,"Impossible d'ecrire dans %s",FICHIER);
                                            		}
                                            		else
                                            		{
                                            			fprintf(out,"%s",tmp);
                                            			fclose(out);
                                            		}
                                            		return ind;
                                            	}
                                            	return -1;
                                            }
                                            


                                            afficher

                                            void afficher(char * s, int deb, int fin)
                                            {
                                            	int i;
                                            	for(i = deb;i<fin;i++)
                                            		putchar(s[i]);
                                            }
                                            


                                            Code complet :

                                            #include <stdio.h>
                                            #include <stdlib.h>
                                            
                                            #define MAX 256
                                            
                                            #define FICHIER "mol.conf"
                                            
                                            typedef struct
                                            {
                                            	char symbole[3];
                                            	double masse_molaire;
                                            } Atome;
                                            
                                            typedef struct
                                            {
                                            	int size;
                                            	Atome t[MAX];
                                            } CPE;
                                            
                                            int addAtome(CPE * cpe,char const * s);
                                            int findAtome(CPE * cpe, char const s[3]);
                                            double getMasseMolaire(CPE * cpe, int n);
                                            double sumMolecule(CPE * cpe, char * s);
                                            int ajouterAtome(CPE * cpe, char * s);
                                            void afficher(char * s, int deb, int fin);
                                            
                                            int main(void)
                                            {
                                            	CPE cpe;
                                            	char buf[1024];
                                            	FILE *in = NULL;
                                            	int i;
                                            	cpe.size = 0;
                                            	in = fopen(FICHIER,"r");
                                            	if(in != NULL)
                                            	{
                                            		while(fgets(buf,1024,in))
                                            			addAtome(&cpe,buf);
                                            		fclose(in);
                                            	}
                                            	printf("Atomes connus :\n");
                                            	for(i = 0;i<cpe.size;i++)
                                            		printf("%s %lf\n",cpe.t[i].symbole,cpe.t[i].masse_molaire);
                                            	printf("> ");
                                            	while(gets(buf))
                                            	{
                                            		double masse;
                                            		if(strcmp(buf,"\n") == 0)
                                            			continue;
                                            		if(strcmp(buf,"exit") == 0)
                                            			break;
                                            		masse = sumMolecule(&cpe,buf);
                                            		if(masse >= 0)
                                            		{
                                            			printf("%s : %f g/mol\n",buf,masse);
                                            		}
                                            		printf("> ");
                                            	}
                                            	return 0;
                                            }
                                            
                                            int addAtome(CPE * cpe,char const * s)
                                            {
                                            	if(cpe->size < MAX)
                                            	{
                                            		static int nb_lignes = 1;
                                            		int tmp = sscanf(s,"%s %lf",&(cpe->t[cpe->size].symbole),&(cpe->t[cpe->size].masse_molaire));
                                            		if(tmp < 2)
                                            		{
                                            			fprintf(stderr,"Erreur ligne %d\n",nb_lignes);
                                            			return -1;
                                            		}
                                            		cpe->size++;
                                            		nb_lignes++;
                                            	}
                                            	else
                                            	{
                                            		fprintf(stderr,"Trop d'atomes\n");
                                            		return -1;
                                            	}
                                            	return cpe->size-1;
                                            }
                                            
                                            int findAtome(CPE * cpe, char const s[3])
                                            {
                                            	int i = 0;
                                            	for(i = 0;i<cpe->size;i++)
                                            	{
                                            		if(strcmp(s,(cpe->t[i]).symbole) == 0)
                                            			return i;
                                            	}
                                            	if(i == cpe->size)
                                            		return -1;
                                            }
                                            
                                            double getMasseMolaire(CPE * cpe, int n)
                                            {
                                            	return (cpe->t[n]).masse_molaire;
                                            }
                                            
                                            double _sumMolecule(CPE * cpe, char * s, int* i)
                                            {
                                            	double somme = 0;
                                            	double somme_tmp = 0;
                                            	int nb_entites = 0;
                                            	int continuer = 1;
                                            	char atome[3];
                                            	int ind_lettre = 0;
                                            	int parenthese = 0;
                                            	int const deb = *i;
                                            
                                            	while(continuer > 0)
                                            	{
                                            		switch(s[*i])
                                            		{
                                            			case '\n':
                                            				s[*i] = '\0';
                                            			case ')':
                                            			case '\0':
                                            				continuer = 0;
                                            				break;
                                            			case '(':
                                            				if(parenthese == 1)
                                            				{
                                            					parenthese = 0;
                                            					if(nb_entites == 0)
                                            					{
                                            						somme += somme_tmp;
                                            						afficher(s,deb,*i);
                                            						printf(" : %f g/mol\n",somme);
                                            					}
                                            					else
                                            					{
                                            						somme += somme_tmp * nb_entites;
                                            						afficher(s,deb,*i);
                                            						printf(" : %f g/mol\n",somme);
                                            						nb_entites = 0;
                                            					}
                                            				}
                                            				else if(ind_lettre != 0)
                                            				{
                                            					atome[ind_lettre] = '\0';
                                            					int ind = findAtome(cpe,atome);
                                            					if(ind < 0)
                                            					{
                                            						fprintf(stderr,"%s non reconnu\n",atome);
                                            						if((ind = ajouterAtome(cpe,atome)) == -1)
                                            							return -1.0;
                                            					}
                                            					if(nb_entites == 0)
                                            					{
                                            						somme += getMasseMolaire(cpe,ind);
                                            						afficher(s,deb,*i);
                                            						printf(" : %f g/mol\n",somme);
                                            					}
                                            					else
                                            					{
                                            						somme += getMasseMolaire(cpe,ind) * nb_entites;
                                            						afficher(s,deb,*i);
                                            						printf(" : %f g/mol\n",somme);
                                            						nb_entites = 0;
                                            					}
                                            				}
                                            				++(*i);
                                            				somme_tmp = _sumMolecule(cpe,s,i);
                                            				if(somme_tmp < 0.0)
                                            					return -1.0;
                                            				parenthese = 1;
                                            				break;
                                            			case '0':
                                            			case '1':
                                            			case '2':
                                            			case '3':
                                            			case '4':
                                            			case '5':
                                            			case '6':
                                            			case '7':
                                            			case '8':
                                            			case '9':
                                            				nb_entites = nb_entites * 10 + (s[*i] - '0');
                                            			case ' ':
                                            			case '\t':
                                            				++(*i);
                                            				break;
                                            			default: //lettre
                                            				if(parenthese == 1)
                                            				{
                                            					parenthese = 0;
                                            					if(nb_entites == 0)
                                            					{
                                            						somme += somme_tmp;
                                            						afficher(s,deb,*i);
                                            						printf(" : %f g/mol\n",somme);
                                            					}
                                            					else
                                            					{
                                            						somme += somme_tmp * nb_entites;
                                            						afficher(s,deb,*i);
                                            						printf(" : %f g/mol\n",somme);
                                            						nb_entites = 0;
                                            					}
                                            				}
                                            				else if((s[*i] & 0x20) == 0) // majuscule
                                            				{
                                            					atome[ind_lettre] = '\0';
                                            					if(ind_lettre != 0)
                                            					{
                                            						int ind = findAtome(cpe,atome);
                                            						if(ind < 0)
                                            						{
                                            							fprintf(stderr,"%s non reconnu\n",atome);
                                            							if((ind = ajouterAtome(cpe,atome)) == -1)
                                            								return -1.0;
                                            						}
                                            						if(nb_entites == 0)
                                            						{
                                            							somme += getMasseMolaire(cpe,ind);
                                            							afficher(s,deb,*i);
                                            							printf(" : %f g/mol\n",somme);
                                            						}
                                            						else
                                            						{
                                            							somme += getMasseMolaire(cpe,ind) * nb_entites;
                                            							afficher(s,deb,*i);
                                            							printf(" : %f g/mol\n",somme);
                                            							nb_entites = 0;
                                            						}
                                            					}
                                            					atome[0] = s[*i];
                                            					ind_lettre = 1;
                                            				}
                                            				else
                                            				{
                                            					atome[ind_lettre] = s[*i];
                                            					++ind_lettre;
                                            				}
                                            				++(*i);
                                            				break;
                                            		}
                                            	}
                                            	if(parenthese == 1)
                                            	{
                                            		parenthese = 0;
                                            		if(nb_entites == 0)
                                            		{
                                            			somme += somme_tmp;
                                            			if(s[*i] != '\0')
                                            			{
                                            				afficher(s,deb,*i);
                                            				printf(" : %f g/mol\n",somme);
                                            			}
                                            		}
                                            		else
                                            		{
                                            			somme += somme_tmp * nb_entites;
                                            			if(s[*i] != '\0')
                                            			{
                                            				afficher(s,deb,*i);
                                            				printf(" : %f g/mol\n",somme);
                                            			}
                                            			nb_entites = 0;
                                            		}
                                            	}
                                            	else
                                            	{
                                            		atome[ind_lettre] = '\0';
                                            		if(ind_lettre != 0)
                                            		{
                                            			int ind = findAtome(cpe,atome);
                                            			if(ind < 0)
                                            			{
                                            				fprintf(stderr,"%s non reconnu\n",atome);
                                            				if((ind = ajouterAtome(cpe,atome)) == -1)
                                            					return -1.0;
                                            			}
                                            			if(nb_entites == 0)
                                            			{
                                            				somme += getMasseMolaire(cpe,ind);
                                            				if(s[*i] != '\0')
                                            				{
                                            					afficher(s,deb,*i);
                                            					printf(" : %f g/mol\n",somme);
                                            				}
                                            			}
                                            			else
                                            			{
                                            				somme += getMasseMolaire(cpe,ind) * nb_entites;
                                            				if(s[*i] != '\0')
                                            				{
                                            					afficher(s,deb,*i);
                                            					printf(" : %f g/mol\n",somme);
                                            				}
                                            				nb_entites = 0;
                                            			}
                                            		}
                                            		else
                                            		{
                                            			int ind = findAtome(cpe,atome);
                                            			if(ind < 0)
                                            			{
                                            				fprintf(stderr,"%s non reconnu\n",atome);
                                            				if((ind = ajouterAtome(cpe,atome)) == -1)
                                            					return -1.0;
                                            			}
                                            			if(nb_entites == 0)
                                            			{
                                            				somme += getMasseMolaire(cpe,ind);
                                            				if(s[*i] != '\0')
                                            				{
                                            					afficher(s,deb,*i);
                                            					printf(" : %f g/mol\n",somme);
                                            				}
                                            			}
                                            			else
                                            			{
                                            				somme += getMasseMolaire(cpe,ind) * nb_entites;
                                            				if(s[*i] != '\0')
                                            				{
                                            					afficher(s,deb,*i);
                                            					printf(" : %f g/mol\n",somme);
                                            				}
                                            				nb_entites = 0;
                                            			}
                                            		}
                                            		atome[0] = s[*i];
                                            		ind_lettre = 1;
                                            	}
                                            	if(s[*i] != '\0')
                                            		++(*i);
                                            	return somme;
                                            }
                                            
                                            double sumMolecule(CPE * cpe, char * s)
                                            {
                                            	int i = 0;
                                            	return _sumMolecule(cpe,s,&i);
                                            }
                                            
                                            int ajouterAtome(CPE * cpe, char * s)
                                            {
                                            	int c,c2;
                                            	double masse;
                                            	char tmp[512];
                                            	FILE* out;
                                            	int ind;
                                            	printf("Souhaitez-vous ajouter l'atome %s ?\n",s);
                                            	while((c = getchar()) != '0' && c != '1' && (c & 0xdf) != 'Y' && (c & 0xdf) != 'O' && (c & 0xdf) != 'N' && c != EOF);
                                            	while((c2 = getchar()) != '\n' && c2 != EOF);
                                            	if((c & 0xdf) == 'Y' || (c & 0xdf) == 'O' || c == '1')
                                            	{
                                            		printf("Masse molaire ?\n");
                                            		if(scanf("%lf",&masse) < 1)
                                            		{
                                            			while((c2 = getchar()) != '\n' && c2 != EOF);
                                            			return -1;
                                            		}
                                            		while((c2 = getchar()) != '\n' && c2 != EOF);
                                            		sprintf(tmp,"%s %f\n",s,masse);
                                            		ind = addAtome(cpe,tmp);
                                            		if(ind < 0)
                                            			return -1;
                                            		out = fopen(FICHIER,"a");
                                            		if(out == NULL)
                                            		{
                                            			fprintf(stderr,"Impossible d'ecrire dans %s",FICHIER);
                                            		}
                                            		else
                                            		{
                                            			fprintf(out,"%s",tmp);
                                            			fclose(out);
                                            		}
                                            		return ind;
                                            	}
                                            	return -1;
                                            }
                                            
                                            void afficher(char * s, int deb, int fin)
                                            {
                                            	int i;
                                            	for(i = deb;i<fin;i++)
                                            		putchar(s[i]);
                                            }
                                            


                                            Résultat :
                                            $ ./a.out
                                            Atomes connus :
                                            C 12.011000
                                            O 15.999000
                                            H 1.007900
                                            He 4.002600
                                            Li 6.941000
                                            Cl 35.453000
                                            Na 22.989000
                                            > NaSO4
                                            Na : 22.989000 g/mol
                                            S non reconnu
                                            Souhaitez-vous ajouter l'atome S ?
                                            o
                                            Masse molaire ?
                                            32.066
                                            NaS : 55.055000 g/mol
                                            NaSO4 : 119.051000 g/mol
                                            > CH3(CH2)5CH3
                                            C : 12.011000 g/mol
                                            CH3 : 15.034700 g/mol
                                            C : 12.011000 g/mol
                                            CH2 : 14.026800 g/mol
                                            CH3(CH2)5 : 85.168700 g/mol
                                            CH3(CH2)5C : 86.176600 g/mol
                                            CH3(CH2)5CH3 : 89.200300 g/mol
                                            > exit
                                            
                                            $ ./a.out
                                            Atomes connus :
                                            C 12.011000
                                            O 15.999000
                                            H 1.007900
                                            He 4.002600
                                            Li 6.941000
                                            Cl 35.453000
                                            Na 22.989000
                                            S 32.066000
                                            > exit
                                            
                                            $
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              1 novembre 2011 à 1:09:46

                                              Tu peux tout rassembler dans un seul ? Comme ça si l'on veut le tester ou l'analyser, on a juste à le copier ou à le lire d'un bloc. On perds en lisibilité paradoxalement en divisant. ;)
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                              "If debbugging is the process of removing bugs, then programming must be the process of putting them in." (Edsger Dijkstra)
                                                1 novembre 2011 à 9:05:24

                                                Citation : schadocalex

                                                Tu peux tout rassembler dans un seul ? Comme ça si l'on veut le tester ou l'analyser, on a juste à le copier ou à le lire d'un bloc. On perds en lisibilité paradoxalement en divisant. ;)


                                                J'ai édité mon message précédent pour ajouter un bloc où on a tout le code.
                                                EDIT : d'ailleurs, l'exemple de la molécule NaSO4 n'existe pas. En effet, Na peut faire 1 liaison (<math>\(Na^+\)</math>) tandis que <math>\(SO_4\)</math> doit en faire 2. En effet, je ne connais pas l'ion <math>\(SO_4^-\)</math> mais connais l'ion <math>\(SO_4^{2-}\)</math>
                                                Un petit exemple avec un ion existant :
                                                $ ./a.out
                                                Atomes connus :
                                                C 12.011000
                                                O 15.999000
                                                H 1.007900
                                                He 4.002600
                                                Li 6.941000
                                                Cl 35.453000
                                                Na 22.989000
                                                S 32.066000
                                                > H2SO4
                                                H2 : 2.015800 g/mol
                                                H2S : 34.081800 g/mol
                                                H2SO4 : 98.077800 g/mol
                                                > exit
                                                
                                                $


                                                L'étape suivante de mon code pourrait consister à trier le tableau pour que la recherche soit plus rapide. Cependant, l'ajout en deviendrait plus lent.
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  1 novembre 2011 à 12:39:17

                                                  Citation : Alienore

                                                  D'ailleurs, l'exemple de la molécule NaSO4 n'existe pas. En effet, Na peut faire 1 liaison (<math>\(Na^+\)</math>) tandis que <math>\(SO_4\)</math> doit en faire 2. En effet, je ne connais pas l'ion <math>\(SO_4^-\)</math> mais connais l'ion <math>\(SO_4^{2-}\)</math>


                                                  En revanche, <math>\(\text{Na$_2$SO$_4$}\)</math> existe. ;)(oui je sais je suis très utile)
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    16 novembre 2011 à 19:45:48

                                                    Coucou. :D

                                                    Je tente de faire l'exercice 1 seulement j'ai un soucis sur la récup' de texte.
                                                    Une fois que je rentre ma lettre et fais entrée Windows me met un rapport d'erreur.
                                                    Je crois que j'ai quelques confusions entre là et ce que je fais à l'IUT en Ada. :-°

                                                    #include <stdio.h>
                                                    #include <stdlib.h>
                                                    #include <ctype.h>
                                                    
                                                    #define LECT carAct = fgetc(fichier);
                                                    
                                                    void lectureFichier (FILE **fichier, char c, double *m)
                                                    {
                                                        char carAct = 0; // Caractère parcourant le fichier.
                                                        int trouve = 0, fact = 10;
                                                    
                                                        LECT
                                                        while (carAct != EOF && trouve != 2) // Tant que l'on a pas fini et pas trouvé.
                                                        {
                                                            if (trouve)
                                                            {
                                                                if (carAct == ' ') // Si le caractère est suivi d'un espace.
                                                                    trouve = 2; // C'est le bon élément : on sort de la boucle.
                                                                else
                                                                    trouve = 0;
                                                            }
                                                            if (carAct == c) // Si le caractère lu est égal à celui trouvé,
                                                                trouve = 1;
                                                    
                                                            LECT
                                                        }
                                                    
                                                        if (trouve == 2) // Si on a trouvé la bonne ligne.
                                                        {
                                                            while (carAct != '\n')
                                                            {
                                                                if(carAct != '.') // Si ce n'est pas la virgule,
                                                                {
                                                                    *m = *m + ((carAct - '0') * fact); // On ajoute à la masse molaire le chiffre * le facteur,
                                                                    fact /= 10; // que l'on divise par 10 à chaque fois.
                                                                }
                                                                LECT
                                                            }
                                                        }
                                                    }
                                                    
                                                    int main()
                                                    {
                                                        char c; // Caracère lu.
                                                        double m = 0; // Masse molaire.
                                                        FILE *fichier = NULL;
                                                    
                                                        if(fichier = fopen("zMol.txt", "r") == NULL)
                                                            printf("Erreur lors de l'ouverture de zMol.txt");
                                                    
                                                        printf("Entrez une molecule :\n--> ");
                                                    
                                                        c = getchar();
                                                        while (c != EOF && c != '\n')
                                                        {
                                                            c = toupper(c);
                                                            lectureFichier(&fichier, c, &m);
                                                            c = getchar();
                                                        }
                                                    
                                                        printf("\n\nLa masse molaire de cette molecule est %f g.mol-1", m);
                                                    
                                                        fclose(fichier);
                                                        return 0;
                                                    }
                                                    



                                                    Merci ! ;)
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      16 novembre 2011 à 19:51:45

                                                      Les rapports d'erreur de Windows sont des segfault.
                                                      Ton compilateur ne râle pas ? Pourtant, fgetc attend un FILE*, pas un FILE**.
                                                      Les formats sont utiles pour ne pas se compliquer la vie.
                                                      fscanf, sscanf,...
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        16 novembre 2011 à 22:23:06

                                                        Ah oui merci ! Avec #define LECT carAct = fgetc(*fichier); ça va mieux.


                                                        Sinon problème pour les calculs. Comme par exemple C ça me met 12.000, ça vient de là :
                                                        if (trouve == 2) // Si on a trouvé la bonne ligne.
                                                        {
                                                                while (carAct != '\n')
                                                                {
                                                                    if(carAct != '.') // Si ce n'est pas la virgule,
                                                                    {
                                                                        *m = *m + ((carAct - '0') * fact); // On ajoute à la masse molaire le chiffre * le facteur,
                                                                        fact /= 10; // que l'on divise par 10 à chaque fois.
                                                                    }
                                                                    LECT
                                                                }
                                                        }
                                                        
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          18 novembre 2011 à 12:24:03

                                                          bonjour

                                                          int trouve = 0, fact = 10;
                                                          


                                                          si tu donnais un type flottant à fact ça fonctionnerait mieux, non?

                                                          Sinon pour éviter des prises de tête : strtod.
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                          Zeste de Savoir, le site qui en a dans le citron !
                                                            20 décembre 2011 à 2:04:12

                                                            Salut à tous,

                                                            Voilà je me lance donc dans ce défi - que j'ai découvert grâce à mon cher Sabeurre que je remercie énormément pour ses conseils - en vous donnant mon code (niveau 5), et oui après en avoir suer sang et eau et avoir crier quelques fois je suis enfin arrivé à faire un programme qui fonctionne parfaitement :D Enfin parfaitement ... tout semble fonctionnait pour ma part.

                                                            Vous le remarquerez aussi j'ai quasiment concentrer tout mon programme dans une seule fonction donc c'est normale si vous la trouvez un peu longue :p

                                                            M'enfin trêves de bavardages et place au code, le voici donc :

                                                            Main.c :
                                                            #include <stdio.h>
                                                            #include <stdlib.h>
                                                            #define TAILLE_MOLECULE 20
                                                            #include "lecture.h"
                                                            
                                                            int main(int argc, char* argv[])
                                                            {
                                                                char Molecule[TAILLE_MOLECULE] = {0};
                                                                double resultat = 0;
                                                                int mode = 0;
                                                            
                                                                printf("Salut et bienvenue dans ce calculateur de masse molaire !\n");
                                                            
                                                                printf("Choisissez votre mode :\n 1 - Calculer la masse molaire d'une molecule\n 2 - Ajouter un atome dans la liste de donnees\n ===> ");
                                                                scanf("%d", &mode);
                                                                viderBuffer();
                                                            
                                                                if (mode == 1)
                                                                {
                                                                    printf("Entrez une molecule => ");
                                                                    lireCaractere(Molecule, TAILLE_MOLECULE);
                                                            
                                                                    resultat = calcul(Molecule);
                                                            
                                                                    printf("\n\nLa masse molaire de votre molecule est de %f g.mol-1", resultat);
                                                                }
                                                                else if (mode == 2)
                                                                {
                                                                    ajouter();
                                                                }
                                                                else
                                                                {
                                                                    printf("\nMauvais choix de mode, le programme va fermer.");
                                                                    exit(0);
                                                                }
                                                            
                                                            
                                                                return 0;
                                                            }
                                                            


                                                            lecture.h
                                                            #ifndef DEF_LECTURE
                                                            #define DEF_LECTURE
                                                            
                                                            void viderBuffer();
                                                            int lireCaractere(char *Molecule, int taille);
                                                            double calcul(char *Molecule);
                                                            void ajouter();
                                                            
                                                            typedef struct
                                                            {
                                                                char symbole[3];
                                                                double masse;
                                                                long coefficient;
                                                            }Element;
                                                            
                                                            
                                                            #endif
                                                            


                                                            lecture.c
                                                            #include <stdio.h>
                                                            #include <stdlib.h>
                                                            #include <string.h>
                                                            #include <ctype.h>
                                                            #include "lecture.h"
                                                            
                                                            void viderBuffer()
                                                            {
                                                                int c = 0;
                                                                while (c != '\n' && c != EOF)
                                                                {
                                                                    c = getchar();
                                                                }
                                                            }
                                                            
                                                            int lireCaractere(char *Molecule, int taille)
                                                            {
                                                                char *Position = NULL;
                                                            
                                                                if (fgets(Molecule, taille, stdin) != NULL)
                                                                {
                                                                    Position = strchr(Molecule, '\n');
                                                                    if (Position != NULL)
                                                                    {
                                                                        *Position = '\0';
                                                                    }
                                                                    else
                                                                    {
                                                                        viderBuffer();
                                                                    }
                                                            
                                                                    return 1;
                                                                }
                                                                else
                                                                {
                                                                    viderBuffer();
                                                            
                                                                    return 0;
                                                                }
                                                            
                                                            }
                                                            
                                                            double calcul(char *Molecule)
                                                            {
                                                                Element Element[10];
                                                                int i = 0, j = 0, m = 0, n = 0;
                                                                long x = 1;
                                                                FILE* fichier = NULL;
                                                                char liste[200] = {0};
                                                                char test[15] = {0};
                                                                char masse[10] = {0};
                                                                char* position = NULL;
                                                                double resultat = 0;
                                                            
                                                                while (i < strlen(Molecule))
                                                                {
                                                                    if (Molecule[i] == '(')
                                                                    {
                                                                        x = strtol(strchr(Molecule, ')') + 1, NULL, 10);
                                                                        i++;
                                                                    }
                                                                    else if (Molecule[i] == ')')
                                                                    {
                                                                        x = 1;
                                                                        i+=2;
                                                                    }
                                                            
                                                                    if (isupper(Molecule[i]) != 0 && islower(Molecule[i+1]) != 0 && isdigit(Molecule[i+2]) != 0)
                                                                    {
                                                                        Element[j].symbole[0] = Molecule[i];
                                                                        Element[j].symbole[1] = Molecule[i+1];
                                                                        Element[j].symbole[2] = '\0';
                                                                        Element[j].coefficient = strtol(Molecule + i + 2, NULL, 10) * x;
                                                                        i+=3;
                                                                    }
                                                                    else if (isupper(Molecule[i]) != 0 && isdigit(Molecule[i+1]) != 0)
                                                                    {
                                                                        Element[j].symbole[0] = Molecule[i];
                                                                        Element[j].symbole[1] = '\0';
                                                                        Element[j].coefficient = strtol(Molecule + i + 1, NULL, 10) * x;
                                                                        i+=2;
                                                                    }
                                                                    else if (isupper(Molecule[i]) && islower(Molecule[i+1]) != 0)
                                                                    {
                                                                        Element[j].symbole[0] = Molecule[i];
                                                                        Element[j].symbole[1] = Molecule[i+1];
                                                                        Element[j].symbole[2] = '\0';
                                                                        Element[j].coefficient = 1 * x;
                                                                        i+=2;
                                                                    }
                                                                    else if (isupper(Molecule[i]) != 0)
                                                                    {
                                                                        Element[j].symbole[0] = Molecule[i];
                                                                        Element[j].symbole[1] = '\0';
                                                                        Element[j].coefficient = 1 * x;
                                                                        i++;
                                                                    }
                                                                    else if (Molecule[i] == ')' || Molecule[i] == '\0')
                                                                    {
                                                                        Element[j].symbole[0] = '\0';
                                                                        Element[j].masse = 0;
                                                                        Element[j].coefficient = 0;
                                                                    }
                                                                    else
                                                                    {
                                                                        printf("Votre molecule n'est pas ecrite de facon correcte.\n");
                                                                        exit(0);
                                                                    }
                                                            
                                                                    j++;
                                                                }
                                                            
                                                            
                                                                fichier = fopen("mm_molecule.txt", "r");
                                                            
                                                                if (fichier == NULL)
                                                                {
                                                                    printf("Impossible d'ouvrir le fichier mm_molecule.txt\n");
                                                                    exit(0);
                                                                }
                                                            
                                                                while (!feof(fichier))
                                                                {
                                                                    fgets(test, 200, fichier);
                                                                    strcat(liste, test);
                                                                }
                                                            
                                                                m = j;
                                                                for (j = 0; j < m; j++)
                                                                {
                                                                    if(strstr(liste, Element[j].symbole) != NULL)
                                                                    {
                                                                        while (n < 10)
                                                                        {
                                                                            position = strstr(liste, Element[j].symbole) + 2 + n;
                                                                            masse[n] = *position;
                                                                            n++;
                                                                        }
                                                                        Element[j].masse = strtod(masse, NULL) * Element[j].coefficient;
                                                                        resultat+= Element[j].masse;
                                                                    }
                                                                    else
                                                                    {
                                                                        printf("\nVotre symbole n'est pas repertorie dans notre liste d'elements chimiques.");
                                                                        exit(0);
                                                                    }
                                                            
                                                                    n = 0;
                                                            
                                                                }
                                                            
                                                                fclose(fichier);
                                                                return resultat;
                                                            }
                                                            
                                                            void ajouter()
                                                            {
                                                                char Atome[3];
                                                                double masse = 0;
                                                                FILE* fichier = fopen("mm_molecule.txt", "r+");
                                                            
                                                                printf("\nRentrez le symbole de l'atome : ");
                                                                lireCaractere(Atome, 3);
                                                                printf("Rentrez sa masse molaire : ");
                                                                scanf("%lf", &masse);
                                                                viderBuffer();
                                                            
                                                                fseek(fichier, 0, SEEK_END);
                                                                fprintf(fichier, "\n%s %f", Atome, masse);
                                                                fclose(fichier);
                                                            
                                                                printf("\nL'atome a ete correctement ajoute dans la liste.");
                                                            }
                                                            


                                                            Etant donné que je viens de le finir à l'instant et qu'il est un peu tard je ne l'ai pas commenté, s'il faut le faire merci de me le dire et je m'en chargerai de suite ;)

                                                            Et aussi, ce programme est mon premier programme après le pendu proposé par M@teo21 dans son tutoriel sur l'apprentissage en C donc n'hésitez pas à me traîner dans la boue et à bien critiquer mon code sur les erreurs ou détails à ne pas faire, je suis ici pour apprendre après tout :p

                                                            Sur ce, bonne journée à tous ;)
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              15 janvier 2012 à 16:26:13

                                                              Bonjour à tous!

                                                              Je commence zmol et je rencontre un petit soucis:
                                                              je voudrais lire mon fichier et mettre ces données dans un tableau: pour cela j'ai créé une fonction get_Tab qui doit me renvoyer le nombre d'éléments de la table et une structure Element composée de deux variables char nom_Atome et double masse_Atome.
                                                              Mais voilà ça ne fonctionne pas comme je voudrais. Je suis sûre que la solution est sous mes yeux, cependant...

                                                              voici le code:

                                                              /*********************************************************************
                                                              * *
                                                              * Ce programme permet le calcul des masses molaires moléculaires *
                                                              * *
                                                              **********************************************************************/

                                                              #include <stdio.h>
                                                              #include <stdlib.h>
                                                              #include "fonction.h"

                                                              int main(int argc, char *argv[])
                                                              {
                                                              char molecule[100] = "";

                                                              int nbElement = 0;
                                                              int atomeTabValid = 0;

                                                              Element Element[112];


                                                              /************************************************************
                                                              * *
                                                              * Recuperation de la molecule saisie par l'utilisateur *
                                                              * *
                                                              ************************************************************/

                                                              printf("entrez une molecule:\n\n");
                                                              printf("--> ");
                                                              scanf("%s", molecule);
                                                              printf("\n\n");
                                                              //printf("molecule vaut: %s", molecule);

                                                              nbElement = get_Tab(Element);
                                                              printf("la table est composee de %d elements\n\n", nbElement);

                                                              atomeTabValid = validAtome(molecule, Element, nbElement);

                                                              return 0;
                                                              }


                                                              /*******************************************************************
                                                              * *
                                                              * Recuperation des donnees du fichier fileElement dans un tableau *
                                                              * La fonction retourne le nombre d'element: nbElementTab *
                                                              * *
                                                              *******************************************************************/
                                                              int get_Tab(Element Element[])
                                                              {
                                                              int nbElementTab = 0;

                                                              FILE *pfichier = fopen("fileElement.txt", "r");

                                                              if(pfichier != NULL){
                                                              printf("ouverture reussi\n\n");
                                                              while(fgetc(pfichier) != EOF){
                                                              fscanf(pfichier, "%s %lf", Element[nbElementTab].nom_Atome, &Element[nbElementTab].masse_Atome);
                                                              nbElementTab++;
                                                              }
                                                              fclose(pfichier);
                                                              printf("Premier element %s a une masse de %f\n\n", Element[0].nom_Atome, Element[0].masse_Atome);
                                                              }
                                                              else{
                                                              printf("Fichier fileElement.txt introuvable\n\n");
                                                              return 0;
                                                              }
                                                              return 0;

                                                              return nbElementTab;
                                                              }


                                                              TabElement.h:

                                                              #ifndef TABELEMENT_H_INCLUDED
                                                              #define TABELEMENT_H_INCLUDED

                                                              typedef struct Element Element;
                                                              struct Element
                                                              {
                                                              char nom_Atome[3];
                                                              double masse_Atome;
                                                              };

                                                              #endif // TABELEMENT_H_INCLUDED



                                                              fonction.h

                                                              #ifndef FONCTION_H_INCLUDED
                                                              #define FONCTION_H_INCLUDED

                                                              #include "TabElement.h"

                                                              int get_Tab(Element Element[]);

                                                              #endif // FONCTION_H_INCLUDED


                                                              console:

                                                              entrez une molecule:

                                                              --> CO


                                                              ouverture reussi

                                                              Premier element 12.01100 a une masse de 0.000000

                                                              la table est composee de 0 elements

                                                              la molecule a 2 atomes


                                                              Process returned 0 (0x0) execution time : 3.424 s
                                                              Press any key to continue.



                                                              Merci pour votre aide!
                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              Celui qui aime à apprendre est bien près du savoir " Confucius

                                                              [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