IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Lire un fichier .ini


Sujet :

C

  1. #1
    Membre averti
    Femme Profil pro
    Inscrit en
    Juin 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 35
    Par défaut Lire un fichier .ini
    Bonjour à tous,

    Je dois lire un fichier .ini et récuperer les valeurs de constantes à partir de leur nom :

    Voici ma fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    double getDefine(char* label)
    {
    	FILE *file; 
    	char c;
    	char word[25];
    	char value[5];
    	int i,j;
    	bool found=false;
    	/* open */
      file = fopen(FIC_INIT, "r"); 
      if(file == NULL){
          fprintf(stdout, "Impossible d'ouvrir le fichier %s\n", FIC_INIT);
          return -1;
      }
    word[0]='\0';
    value[0]='\0';
    i=0;
    c = fgetc (file);
      do {
     
    	if (c=='#') 
    	{
    		while(c!='\n')
    		{
    			c=fgetc(file);
    		}
    	}
    	else if (c=='\n')
    	{
    		while(c=='\n')
    		{
    			c=fgetc(file);
    		}
    	}
    	else if (c==' ')
    	{
    		while(c==' ')
    		{
    			c=fgetc(file);
    		}
    	}
          	else if (c == '=') 
    	{
    		word[i]='\0';
    		fprintf(stdout, "oh '%s'\n", word);
    		fprintf(stdout, "%d\n", strcmp(label,word));
    		if(strcmp(label,word)==0)
    		{
     
    			j=0;
    			while(c!='\n')
    			{
    				c=fgetc(file);
    				while(c==' ')
    				{
    					c=fgetc(file);
    				}
    				value[j]=c;
    				j++;
    			}
    			value[j]='\0';
    			fprintf(stdout, "%s et %f\n", word, atof(value));
    			found=true;
    		}
    		else
    		{
    			word[0]='\0';
    			value[0]='\0';
    			while(c!='\n')
    			{
    				c=fgetc(file);
    			}
    			i=0;
    		}
    	}
    	else 
    	{
    		word[i]=c;
    		i++;
    		c=fgetc(file);
    	}
        } while (c != EOF && found==false);
     
    	/* close */
      if(fclose(file) == EOF) {
          fprintf(stdout,"Probleme de fermeture du fichier %s", FIC_INIT);
           return -1;
      }
     
    if (found==false)
    {
    	return -1;
    }
    return atof(value);
    }
    }
    Mon fichier .ini :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #Commentaire à être ignoré
     
     
    WORD0 = 1.0
     
    WORD1 = 1.0
    WORD2 = 1.0
     
    WORD3 = 1.0
     
    WORD4 = 1.0
     
    WORD5 = 1.0
     
    WORD6 = 1.0
     
    WORD7 = 1.0
    Lorsque je lance ma fonction comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    double valeur;
    valeur=getDefine("WORD0");
    fprintf(stdout,"%f\n", valeur);
    J'ai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    WORD0'
    1
    WORD1'
    1
    oh 'WORD2'
    -1
    WORD3'
    1
    WORD4'
    1
    WORD5'
    1
    WORD6'
    1
    WORD7'
    1
    -1.000000
    Donc le strcmp me renvoie 1

    Je ne vois pas pourquoi ça coupe à chaque fois que j'ai un saut de ligne juste avant...

    Au sinon, des conseils d'optimisation ?

    Merci

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Août 2007
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 179
    Par défaut
    Bonjour,

    Petite remarque : le type bool n'existe pas en C

    J'ai l'impression que lorsque tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(strcmp(label,word)==1)
    Tu t'attends à ce que ce soit le cas si les deux chaines sont égales. En fait strcmp renvoie 0 si les deux chaines sont égales.

    Sinon cette partie est assez dangeureuse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    		else
    		{
    			word[0]='\0';
    			value[0]='\0';
    			while(c!='\n')
    			{
    				c=fgetc(file);
    			}
    			i=0;
    		}
    En effet tu fais ça dans le cas où ce qu'il y a après le '=' ne te convient pas, en allant directement à la ligne tu risque d'entrer dans une boucle infinie si ton fichier ne se termine pas par un retour à la ligne (avant EOF)

  3. #3
    Membre averti
    Femme Profil pro
    Inscrit en
    Juin 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 35
    Par défaut
    Oups j'ai copié collé le mauvais code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if(strcmp(label,word)==1)
    est en fait pour les résultats obtenus précédemment
    if(strcmp(label,word)==0)
    Donc le problème est toujours la...

  4. #4
    Membre chevronné

    Profil pro
    Inscrit en
    Août 2007
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 179
    Par défaut
    Ah, ben alors je sais pas trop parce que chez moi en mettant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(strcmp(label,word)==0)
    (et en remplaçant le bool par un int et les true et false par des 1 et des 0) ça à l'air de fonctionner, en tout cas ça affiche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    oh 'WORD0'
    0
    WORD0 et 0.000000
    0.000000
    Tu es sûr qu'il n'y a rien d'autre dans ton code qui puisse poser problème?

  5. #5
    Membre averti
    Femme Profil pro
    Inscrit en
    Juin 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 35
    Par défaut
    Bah le truc c'est que c'est censé afficher
    car WORD0 = 1.0 dans le fichier .ini

    Mais c'est bon j'ai trouvé

    Et pour bool j'ai un include #include <stdbool.h>
    Ca reste du C?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    double getDefine(char* label)
    {
    	FILE *file; 
    	char c;
    	char word[25];
    	char value[5];
    	int i,j;
    	bool found=false;
    	/* open */
      file = fopen(FIC_INIT, "r"); 
      if(file == NULL){
          fprintf(stdout, "Can not open file %s\n", FIC_INIT);
          return -1;
      }
    word[0]='\0';
    value[0]='\0';
    i=0;
    c = fgetc (file);
      do {
     
    	if (c=='#') 
    	{
    		while(c!='\n' && c!='\r' && c!=EOF)
    		{
     
    			c=fgetc(file);
    		}
    	}
    	else if (c=='\n')
    	{
    		while(c=='\n' || c=='\r')
    		{
     
    			c=fgetc(file);
    		}
    	}
    	else if (c=='\r')
    	{
     
    		while(c=='\n' || c=='\r')
    		{
     
    			c=fgetc(file);
     
    		}
    	}
    	else if (c==' ')
    	{
    		while(c==' ')
    		{
    			c=fgetc(file);
    		}
    	}
          	else if (c == '=') 
    	{
    		word[i]='\0';
    		if(strcmp(label,word)==0)
    		{
     
    			j=0;
    			while(c!='\n' && c!=EOF)
    			{
    				c=fgetc(file);
    				while(c==' ')
    				{
    					c=fgetc(file);
    				}
    				value[j]=c;
    				j++;
    			}
    			value[j]='\0';
    			found=true;
    		}
    		else
    		{
    			word[0]='\0';
    			value[0]='\0';
    			while(c!='\n' && c!=EOF)
    			{
     
    				c=fgetc(file);
    			}
    			i=0;
    		}
    	}
    	else 
    	{
    		word[i]=c;
    		i++;
    		c=fgetc(file);
    	}
        } while (c != EOF && found==false);
     
    	/* close */
      if(fclose(file) == EOF) {
          fprintf(stdout,"Can not close file %s", FIC_INIT);
           return -1;
      }
     
    if (found==false)
    {
    	return -1;
    }
    return atof(value);
    }
    Voila la fonction =) J'avais oublié les '\r'

    Merci
    et si quelqu'un a des solutions d'optimisation je suis prenante!

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Pythéas
    Petite remarque : le type bool n'existe pas en C
    Si tu codes en C99, tu as un type booléen à ta disposition
    http://c.developpez.com/faq/index.ph...ral#TYPES_bool

    Et pour bool j'ai un include #include <stdbool.h>
    Ca reste du C?
    Ca reste du C bien sûr. Regarde le lien juste au dessus.

  7. #7
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    pourquoi un algorithme a base de fgetc?

    Visiblement tes informations sont données par lignes, tu peux extraire un ligne avec fgets et ensuite analyser la ligne entière.

    je pense que cela pourra simplifier le code et ce sera plus léger en terme d'appel système.

  8. #8
    Membre chevronné

    Profil pro
    Inscrit en
    Août 2007
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 179
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Si tu codes en C99, tu as un type booléen à ta disposition
    http://c.developpez.com/faq/index.ph...ral#TYPES_bool

    Ca reste du C bien sûr. Regarde le lien juste au dessus.
    Ah, ok, j'avais déjà vu ça mais je ne pensais pas que c'était standard, au temps pour moi

    Sinon la fonction a vraiment l'air de marcher chez moi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("getDefine(\"WORD0\") = %f\n", getDefine("WORD0"));
    affiche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    getDefine("WORD0") = 1.000000

    Bon c'est une question idiote mais on sait jamais : tu as écrit que tu appeles la fonction comme il suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    double valeur;
    getDefine("WORD0");
    fprintf(stdout,"%f\n", valeur);
    peut être as-tu simplement oublié de renvoyer la valeur retournée par la fonction dans la variable valeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    double valeur;
    valeur = getDefine("WORD0");
    fprintf(stdout,"%f\n", valeur);

  9. #9
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    ou un autre possibilité avec fscanf qui te retournera le nombre d'arguments correctement lus.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    char key[256];
    double value;
    if (fscanf(file,"%s = %f",&key,&value) == 2)
    {
      printf("Have read %s = %f\n",key,value);
    }
    bon je n'ai pas de compilateur sous la main, mais l'idée est là.


    autre suggestion pour ton programme, il faudrait essayer de ne lire qu'une seule fois le fichier.

    En effet chaque appel a getDefine pour obtenir un champ ouvre le fichier, le parcours et ferme le fichier, c'est assez consommateur.

    Avoir une procédure d'initialisation qui lise tout les champs au départ et les stocke dans un tableau pour que tu puisse ensuite les récupérer en appelant getDefine serait moins couteux.

  10. #10
    Membre averti
    Femme Profil pro
    Inscrit en
    Juin 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 35
    Par défaut
    peut être as-tu simplement oublié de renvoyer la valeur retournée par la fonction dans la variable valeur
    Désolé c'est encore une erreur de copié collé ...
    J'avais bien renvoyé la valeur retournée dans la variable.
    J'ai édité mon 1er message en corrigeant les erreurs de copié collé.

    pourquoi un algorithme a base de fgetc?

    Visiblement tes informations sont données par lignes, tu peux extraire un ligne avec fgets et ensuite analyser la ligne entière.

    je pense que cela pourra simplifier le code et ce sera plus léger en terme d'appel système.
    Merci j'ai fait ça!

    ou un autre possibilité avec fscanf qui te retournera le nombre d'arguments correctement lus.
    Intéressant ! Un truc que je vais essayer de tester

    autre suggestion pour ton programme, il faudrait essayer de ne lire qu'une seule fois le fichier.

    En effet chaque appel a getDefine pour obtenir un champ ouvre le fichier, le parcours et ferme le fichier, c'est assez consommateur.

    Avoir une procédure d'initialisation qui lise tout les champs au départ et les stocke dans un tableau pour que tu puisse ensuite les récupérer en appelant getDefine serait moins couteux.
    Sympa également! je vais le faire!
    Cependant, mes valeurs récupérées ne seront pas rajouté dans dans les mêmes endroits...
    Un tableau global? dans un fichier de config, récupérable par plusieurs fonctions c'est possible?

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

Discussions similaires

  1. Comment lire un fichier Ini ?
    Par aloisio11 dans le forum ASP.NET
    Réponses: 3
    Dernier message: 31/10/2007, 19h07
  2. Lire un fichier INI sur le net
    Par Faith's Fall dans le forum C++Builder
    Réponses: 6
    Dernier message: 14/01/2007, 19h48
  3. Lire/écrire fichier .ini
    Par chillansky dans le forum VBScript
    Réponses: 2
    Dernier message: 03/10/2006, 16h56
  4. Lire un fichier .ini sous Linux
    Par cheprod dans le forum Linux
    Réponses: 2
    Dernier message: 26/04/2006, 17h34
  5. Probleme pour lire un fichier Ini
    Par Sebinou dans le forum C++Builder
    Réponses: 11
    Dernier message: 10/03/2004, 23h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo