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 :

Ouvrir un fichier en "global"?


Sujet :

C

  1. #1
    Membre régulier Avatar de mikhailo
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    78
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 78
    Points : 75
    Points
    75
    Par défaut Ouvrir un fichier en "global" / optimisation du temps d'exécution
    Bonjour,

    Voici un autre petit souci que je rencontre. J'ai un programme qui a la structure suivante: le programme principal, et deux modules .h. Un des modules contient une fonction de recherche de mots sur un fichier texte, et le programme principal appelle cette fonction dans une boucle qui se répète beaucoup (très beaucoup) de fois.

    Au bout de environ 10k itérations (ça dépend des ordinateurs), j'ai un segfault.

    La question est: est-il possible que cela provienne du fait que l'on charge en mémoire et referme sans arrêt un fichier (qui fait 40 mégas)? Et si oui, y a-t-il un moyen de déclarer l'ouverture du fichier en question de façon globale, à ce que la fonction de recherche qui se trouve dans le module le voie? (ce qui éviterait donc de l'ouvrir et le refermer des milliers de fois).
    "Les hommes et les femmes qui, sans bouger de leur bureau ou de leur bibliotheque, sans développer leur puissance corporelle et leurs infinies dimensions, parviennent, par une opération de la conscience, à une tristesse pessimiste qui se pretend lucide ne font que constater, sans le savoir, que toute identification du multiple de la vie à la vacuite de la conscience mène inévitablement à ce pessimisme et cette impuissance."

    extrait de "La fragilité" de Benasayag

  2. #2
    Membre régulier Avatar de mikhailo
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    78
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 78
    Points : 75
    Points
    75
    Par défaut
    Eh bien, suffisait que je poste ici après plusieurs jours de désespoir, et quelqu'un m'a aidé à trouver la solution de la chose:



    1° Effectivement, des demandes d'allocation de mémoire en trop grand nombre, que ce soit avec un fopen() ou un malloc() peuvent provoquer un segfault;



    2° Voici comment faire pour éviter cela:

    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
    #include <diverses_libs.h>
     
    // déclaration de variables globales relatives à fonction_annexe()
    FILE* fichier;
    char* ligne_renvoyee;
     
     
     
    char* fonction_annexe(char input[])
    {
    //diverses opérations sur le fichier;
     
    	return ligne_renvoyee;
    }
     
     
     
     
    int main(int argc, char** argv[})
    {
    	char* result;
     
    //affectation des variables relatives à fonction_annexe()
    	fichier = fopen(chemin_du_fichier, "r");
    	ligne_renvoyee = (char*)malloc(200);
     
    	while (true)
    	{
    //opérations diverses
    		result = fonction_annexe(argv[1]);
    	}
    	fclose(fichier);
    	return result;
    }

    Il faut juste penser à placer le curseur au début du fichier à chaque fois, pour qu'à chaque boucle il soit comme si l'on venait de l'ouvrir, avec fseek(fichier, 0, SEEK_SET).
    "Les hommes et les femmes qui, sans bouger de leur bureau ou de leur bibliotheque, sans développer leur puissance corporelle et leurs infinies dimensions, parviennent, par une opération de la conscience, à une tristesse pessimiste qui se pretend lucide ne font que constater, sans le savoir, que toute identification du multiple de la vie à la vacuite de la conscience mène inévitablement à ce pessimisme et cette impuissance."

    extrait de "La fragilité" de Benasayag

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Bonsoir,

    Citation Envoyé par mikhailo Voir le message
    Voici un autre petit souci que je rencontre. J'ai un programme qui a la structure suivante: le programme principal, et deux modules .h. Un des modules contient une fonction de recherche de mots sur un fichier texte, et le programme principal appelle cette fonction dans une boucle qui se répète beaucoup (très beaucoup) de fois.
    Les fichiers « *.h » servent à contenir les prototypes de fonctions (headers), les déclarations de toutes sortes, les macros, etc. mais pas le code ! Si tu veux faire une compilation séparée, il faut utiliser plusieurs fichiers *.c.

    Citation Envoyé par mikhailo Voir le message
    1° Effectivement, des demandes d'allocation de mémoire en trop grand nombre, que ce soit avec un fopen() ou un malloc() peuvent provoquer un segfault;
    Non, pas directement. Appeler trop souvent malloc() ou fopen() peut conduire à épuiser les ressources (ou mettre le système à genoux) et seulement si tu ne les libères pas entretemps. Si les ressources sont épuisées, malloc() et fopen() renvoient NULL si elles ont échoué.

    Si segfault il y a, c'est que soit tu ignores la valeur de retour de ces fonctions, soit le problème ne se trouve pas là où tu le crois.

    2° Voici comment faire pour éviter cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include <diverses_libs.h>
     
    // déclaration de variables globales relatives à fonction_annexe()
    FILE* fichier;
    char* ligne_renvoyee;
    Les variables globales, c'est mal. Surtout si leur seule utilité est de permettre à deux fonctions de communiquer. Tu peux tout-à-fait passer le descripteur « fichier » en argument de ta fonction. En plus, tu n'auras même pas besoin de modifier son code, et tu pourras manipuler plusieurs fichiers à la fois sans avoir besoin de refermer le premier avant (chose qu'il faudra quand même faire si tu ne comptes plus l'utiliser dans un avenir immédiat).

    Il faut juste penser à placer le curseur au début du fichier à chaque fois, pour qu'à chaque boucle il soit comme si l'on venait de l'ouvrir, avec fseek(fichier, 0, SEEK_SET).
    C'est effectivement mieux que de fermer et le rouvrir systématiquement mais, d'une part, on ne voit nullement apparaître cette ligne dans le code que tu nous as donné, les « diverses opérations » ne nous aidant pas à nous faire une idée et, d'autre part, ce n'est sûrement pas cela qui provoque ta segfault. Par contre, il y a une erreur à ce niveau :

    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
    #include <diverses_libs.h>
    
    // déclaration de variables globales relatives à fonction_annexe()
    FILE* fichier;
    char* ligne_renvoyee;
    
    char* fonction_annexe(char input[])
    {
            //diverses opérations sur le fichier;
    	return ligne_renvoyee; // Voir n° 1
    }
    
    int main(int argc, char** argv[})
    {
    	char* result;
    
            //affectation des variables relatives à fonction_annexe()
    	fichier = fopen(chemin_du_fichier, "r");
    	ligne_renvoyee = (char*)malloc(200); // Voir n°2
    
    	while (true)
    	{
                    //opérations diverses
    		result = fonction_annexe(argv[1]); // Voir n°3
    	}
    
    	fclose(fichier);
    	return result; // Voir n° 4
    }
    1. Tu renvoies la valeur d'une variable globale. À quoi cela sert-il ?
    2. Tu alloues 200 octets, mais tu ne les libères jamais !
    3. « result » prendra ici la valeur de la variable globale « ligne_renvoyee », ce qui, encore une fois, ne sert à rien !
    4. Ça c'est absolument faux. Ta fonction main() est de type « int » mais tu renvoies un « char * », ce qui n'a aucun sens. Le pointeur lui-même pointe vers une zone de mémoire allouée par le processus et qui sera donc détruite avec lui. Quelque soit l'entité qui héritera du code de retour de ton processus, elle n'obtiendra rien de valable.


    Tout cela ressemble beaucoup à de mauvaises habitudes héritées de Java. Est-ce le cas ?

    Bonne chance.

  4. #4
    Membre régulier Avatar de mikhailo
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    78
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 78
    Points : 75
    Points
    75
    Par défaut
    Bonjour, et merci pour ta réponse détaillée. Je n'ai pas mis le code complet de la chose pensant que ce ne serait pas intéressant pour tout le monde, mais je vais le mettre pour que tu voies mieux la tête du truc:

    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
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
     
     
    #define DICO "lefff-2.1.txt"
    #define TAILLE_LIGNE_MAX 200
     
     
     
    /*Déclaration des variables globales relatives à rechercheDichotomique() */
    FILE* FICHIER_DICO;
    char* LIGNE_RENVOYEE;
     
     
     
     
    /*
    Extrait une partie du mot, comprise entre les indices i et j. On suppose:
    i < j;
    j <= (strlen(mot) - 1);
    */
     
    char* extractPart(char mot[], int i, int j)
    {
    	char* partie = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
    	int k = 0;
     
    	for (k = i; k <= j; k++)
    	{
    		partie[k-i] = mot[k];
    	}
    	return partie;
    }
     
     
     
     
     
     
    /*
    Fonction concaténant en un mot deux mots prix en argument.
    */
    char* concateneMots(char mot1[], char mot2[])
    {
    	char* concatenation = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
     
    	strcpy(concatenation, mot1);
    	strcat(concatenation, mot2);
     
    	return concatenation;
    }
     
     
     
     
     
     
     
     
     
     
     
     
    int nombreLignes(char chemin[])
    {
    	int nombre_lignes = 0;
    	char c[200];
     
    	FILE* fichier = NULL;
    	fichier = fopen(chemin, "r");
     
    	while (fgets(c, TAILLE_LIGNE_MAX, fichier) != NULL)
    	{
    		nombre_lignes++;
    	}
     
    	fclose(fichier);
    	return nombre_lignes;
    }
     
     
     
     
     
     
    /*
    accoutrée		v	[pred='accoutrer_____1<obj:(sn),objde:(de-sn),suj:(par-sn)>',cat=v,@passive,@être,@Kfs]
    */
     
    char* partOfSpeech(char ligne_dico[])
    {
    	char* mot = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
    	int* nombre = (int*)malloc(TAILLE_LIGNE_MAX * sizeof(int));
    	char* classeg = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
    	sscanf(ligne_dico, "%s %d %s", mot, nombre, classeg);
    	if (*nombre == 0)
    	{
    		sscanf(ligne_dico, "%s %s", mot, classeg);
    	}
     
    	return classeg;
    }
     
    /*
    verbe, adjectif, pronom, nom commun, (nom propre), adverbe, *conjonction de coordinations, *préposition
    v	adj	pro		nc	np		adv	coo				prep
    conjonction de subordination,			determinant,
    csu(afin que)			cld(lui)	det
     
    */
     
     
     
     
    /*
    Fonction qui extrait le mot de la ligne du dictionnaire correspondante.
    */
    char* getMot(char ligne_dico[], char mot_recup[])
    {
    	sscanf(ligne_dico, "%s", mot_recup);
    	return mot_recup;
    }
     
     
     
     
     
     
     
     
     
     
    char* rechercheDichotomique(char mot[])
    {
    	int stop = 0;
    	int position_current = 0;
    	int n = 2;
    	int signe = 1;
    	int etape = 0;
    	int modificateur = 0;
    	int k = 0;
    	int l = 0;
    	int leng = 0;
    	char aux[TAILLE_LIGNE_MAX];
    	char mot_lu[TAILLE_LIGNE_MAX];
    	char c[1];
     
    	fseek(FICHIER_DICO, 0, SEEK_END);
    	int taille_dico = ftell(FICHIER_DICO);
    	fseek(FICHIER_DICO, 0, SEEK_SET);
     
    	while (stop != 1)
    	{
    		if (position_current%2 == 0)
    		{
    			modificateur = taille_dico/n;
    		}
    		else
    		{
    			modificateur = ((int)taille_dico/(n)) + 1;
    		}
     
    		if (modificateur < k)
    		{
    			modificateur = k;
    		}
     
    		position_current = position_current + signe*(modificateur);
     
    		if (position_current < 0)
    		{
    			position_current = position_current + modificateur - l;
    		}
     
     
    		etape = etape + 1;
    		n = n * 2;
     
    		fseek(FICHIER_DICO, position_current, SEEK_SET);
    		l = 0;
     
    		while((c[0] = fgetc(FICHIER_DICO)) != '\n')
           		{	
        			fseek(FICHIER_DICO, -2, SEEK_CUR);
    			l = l + 1;
     
    		}
    		position_current = position_current - l;		
     
     
    		fscanf(FICHIER_DICO, "%s", mot_lu);
    		leng = strlen(mot_lu);
    /*
    		printf("etape %d, position dans le fichier: %d, pas de la recherche: %d\n", etape, position_current, modificateur);
    		printf("mot lu: %s\n", mot_lu);
    		printf("comparaison entre %s et '%s': %d\n\n", mot_lu, mot, strcmp(mot_lu, mot));
    */		
    		if (etape > 25)
    		{
    			fseek(FICHIER_DICO, 0, SEEK_SET);
    			return "*error";
    		}
    		if (strcmp(mot_lu, mot) == 1)
    		{
    			signe = -1;
    			k = 24;
    			while ((c[0] = fgetc(FICHIER_DICO)) != '\n')
    			{
    				k = k + 1;
    			}
     
    			fseek(FICHIER_DICO, -k, SEEK_CUR);
     
    		}
    		if (strcmp(mot_lu, mot) == -1)
    		{
    			signe = 1;
    			k = 24;
    			while ((c[0] = fgetc(FICHIER_DICO)) != '\n')
    			{
    				k = k + 1;
    			}
     
    			fseek(FICHIER_DICO, -k, SEEK_CUR);
     
    		}		
    		if (strcmp(mot_lu, mot) == 0)
    		{
    /*			printf("%s = %s, recherche terminee en %d etapes!\n", mot_lu, mot, etape);*/
    			stop = 1;
    		}
    	}	
     
    	fseek(FICHIER_DICO, -leng, SEEK_CUR);
    	fgets(aux, TAILLE_LIGNE_MAX, FICHIER_DICO);
    	strcpy(LIGNE_RENVOYEE, aux);
    /*	
    	printf("taille du fichier: %d octets\n", taille_dico);
    */	
    	fseek(FICHIER_DICO, 0, SEEK_SET);
    	return LIGNE_RENVOYEE;
    }
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    void chercheAmbiguite(char mot[], char exception1[], char exception2[])
    {
    	int i = 0;
    	int length = strlen(mot);
    	char* part1;
    	char* part2;
     
    	for (i = 0; i < length; i++)
    	{
    		part1 = extractPart(mot, 0, i);
    		part2 = extractPart(mot, i+1, length-1);
     
    		if ((strcmp(part1, exception1) != 0) && (strcmp(part1, exception2) != 0) && (strcmp(part2, exception1) != 0) && (strcmp(part2, exception2) != 0))
    		{
    /*
    			printf("%s %s\n", part1, part2);
    */
    			if ((rechercheDichotomique(part1) != "*error") && (strlen(part1) > 1))
    			{
    				if ((rechercheDichotomique(part2) != "*error") && (strlen(part2) > 1))
    				{
    					printf("%s %s   <<< concaténation initiale\n%s %s   <<< partitionnement alternatif; URL équivoque valable!\n", exception1, exception2, part1, part2);
    				}
    			}
    		}
    	}
    }
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    int main(int argc, char ** argv)
    {	
     
    	if (argc != 2)
    	{
    		printf("Un seul mot en argument à la fois, merci.\n");
    		return 0;
    	}
     
    	int i = 0;
    	int nombre_lignes;
    	char* result;
    	char* result2;
    	char ligne_lue[TAILLE_LIGNE_MAX];
    	char* mot_recup = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
     
    /*Affectation des variables relatives à rechercheDichotomique() */	
    	FICHIER_DICO = fopen(DICO, "r");
    	LIGNE_RENVOYEE = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
     
     
    	result = rechercheDichotomique(argv[1]);
     
    	if (strcmp(result, "*error") != 0)
    	{
    		result2 = partOfSpeech(result);
    		printf("%s", result);
    		printf("Classe grammaticale = %s\n", result2);
    	}
    	else
    	{
    		printf("Le mot propose ne fait pas partie du dictionnaire :'-)\n");
    	}
     
    	nombre_lignes = nombreLignes(DICO);	
     
    	FILE* fichier = NULL;
    	fichier = fopen(DICO, "r");
     
    	for (i = 0; i < nombre_lignes; i++)
    	{
    		fgets(ligne_lue, TAILLE_LIGNE_MAX, fichier);
    		getMot(ligne_lue, mot_recup);
    		if (i%1000 == 0)
    		{
    			printf("%dème mot lu = %s\n", i, mot_recup);
    		}
    		chercheAmbiguite(concateneMots(argv[1], mot_recup), argv[1], mot_recup);
    		chercheAmbiguite(concateneMots(mot_recup, argv[1]), mot_recup, argv[1]);
    	}
    	printf("Recherche terminée! :'-)\n");
    	fclose(FICHIER_DICO);
    	fclose(fichier);
    	return 0;
    }
    Le fichier dictionnaire utilisé peut se télécharger ici: http://www.labri.fr/perso/clement/le...ff-2.1.txt.bz2 , et il faut supprimer les lignes du début contenant les CGU ainsi que quelques lignes inutiles à la fin du fichier pour que la recherche dichotomique fonctionne comme il faut.

    Pour les variables globales, je sais que c'est Mal dans l'absolu, mais c'est un de mes profs qui m'a dit que dans ce cas, je peux le faire - et effectivement, ça a résolu mon problème de segfault. Pour le reste de tes "reproches" à mon code, j'espère que le voir en entier répond à ces questions:
    1° Je renvoie la valeur d'une var globale car je la modifie à chaque itération;
    2° Pour la libération, je croyais qu'elle se faisait automatiquement lorsque le programme terminait - si ce n'est pas le cas, je devrai rajouter un free();
    3° Dans le code effectif, ce n'est pas le cas a priori;
    4° Idem, je me suis un peu planté en schématisant la chose au lieu de poster le vrai code =)


    Quant aux mauvaises habitudes, eh bien, en fait ça ne vient pas de Java. Je suis en licence d'info, mais j'y suis entré par équivalence, et je n'ai jamais vraiment fait d'info avant, donc j'ai appris à faire du C au premier semestre... donc mea culpa pour mes maladresses =)




    En tout cas... Je viens de refaire le test, et cette fois-ci j'ai également un segfault, mais plus après test de 15k mots du dico, mais 195k. Donc sortir le fopen et le malloc de la fonction rechercheDichotomique a l'air d'avoir aidé, mais pas résolu le problème...
    "Les hommes et les femmes qui, sans bouger de leur bureau ou de leur bibliotheque, sans développer leur puissance corporelle et leurs infinies dimensions, parviennent, par une opération de la conscience, à une tristesse pessimiste qui se pretend lucide ne font que constater, sans le savoir, que toute identification du multiple de la vie à la vacuite de la conscience mène inévitablement à ce pessimisme et cette impuissance."

    extrait de "La fragilité" de Benasayag

  5. #5
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    En jetant un coup d'œil rapide à ton programme, il y a au moins trois problèmes assez important :

    • Un non respect du const-correctness.
    • Énormément d'allocation mais aucune libération.
    • Aucun test sur les valeurs de retours des fonctions malloc() et fopen().


    Le second point peut conduire, comme l'a précédemment fait remarquer Obsidian, à un manque de ressource.
    Le troisième peut conduire à un crash lorsque malloc() retourne NULL pour indiquer un échec d'allocation[1].



    [1] Petite digression au passage, suivant la manière dont est utilisé la mémoire alloué, le test du retour de malloc() ne prévient pas toujours à lui seul les problème lorsque l'allocateur mémoire utilise la stratégie appelé "Optimistic memory allocation"

  6. #6
    Membre régulier Avatar de mikhailo
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    78
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 78
    Points : 75
    Points
    75
    Par défaut
    Pour les tests de retour de malloc() et fopen() je suis d'accord, je vais le rajouter.

    En revanche, qu'entends-tu par non respect de const-correctness?

    Et pour ce qui est des allocations et pas de libérations:
    • Le fopen() et les malloc() du main ne sont appelés qu'une fois car à l'extérieur de toute boucle, donc certes il est plus propre de free() ça à la fin du programme, mais ce n'est pas censé faire planter l'exécution de la boucle
    • Je peux "sortir" de la même façon le malloc() de la fonction concateneMots et le free() à la fin de l'exécution; pas de soucis car à chaque fois je fais un strcpy() dans la variable;
    • Ce qui fait que dans la boucle il ne reste que le malloc() de la fonction extractPart. J'ai déjà testé, si je le "sors" de la même façon, ça donne n'importe quoi au niveau de l'output; il faut vraiment que ce soit reinitialisé à chaque fois. Et je ne peux pas le free(), car je return la variable en question!


    Que devrais-je faire pour remédier à ça?
    "Les hommes et les femmes qui, sans bouger de leur bureau ou de leur bibliotheque, sans développer leur puissance corporelle et leurs infinies dimensions, parviennent, par une opération de la conscience, à une tristesse pessimiste qui se pretend lucide ne font que constater, sans le savoir, que toute identification du multiple de la vie à la vacuite de la conscience mène inévitablement à ce pessimisme et cette impuissance."

    extrait de "La fragilité" de Benasayag

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par mikhailo Voir le message
    Le fopen() et les malloc() du main ne sont appelés qu'une fois car à l'extérieur de toute boucle, donc certes il est plus propre de free() ça à la fin du programme, mais ce n'est pas censé faire planter l'exécution de la boucle
    C'était un conseil donné de façon générale. Un programme en C c'est comme des poupées russes. Ce qui a été ouvert/réservé doit être ensuite libéré/fermé

    Citation Envoyé par mikhailo Voir le message
    Ce qui fait que dans la boucle il ne reste que le malloc() de la fonction extractPart. J'ai déjà testé, si je le "sors" de la même façon, ça donne n'importe quoi au niveau de l'output; il faut vraiment que ce soit reinitialisé à chaque fois. Et je ne peux pas le free(), car je return la variable en question!
    Tu es donc conscient que ta fonction "extractPart" alloue de la mémoire et renvoie ensuite à l'appelant la zone allouée. Donc ta fonction se comporte exactement comme un malloc(). Donc aucun problème pour, une fois que t'as fini de te servir de l'espace alloué, tu le libères via free().

    Citation Envoyé par mikhailo Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    char* partOfSpeech(char ligne_dico[])
    {
    	char* mot = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
    	int* nombre = (int*)malloc(TAILLE_LIGNE_MAX * sizeof(int));
    	char* classeg = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
    	sscanf(ligne_dico, "%s %d %s", mot, nombre, classeg);
    	if (*nombre == 0)
    	{
    		sscanf(ligne_dico, "%s %s", mot, classeg);
    	}
     
    	return classeg;
    }
    Hum... tu alloues des zones mémoires qui seront stockées dans "mot" et "nombre" et tu perds ces variables en quittant la fonction. Tu libères les zones allouées comment ???

    Citation Envoyé par mikhailo Voir le message
    Que devrais-je faire pour remédier à ça?
    Attention, ton topic est marqué "résolu". Je n'y suis venu que par hasard (parce que c'était toi le posteur). Si tu dois avoir d'autres questions et que tu veux que des gens viennent voir pour t'aider, faut modifier ça...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Membre régulier Avatar de mikhailo
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    78
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 78
    Points : 75
    Points
    75
    Par défaut
    Merci du conseil ^^

    Donc en fait, si j'écris:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    char* extractPart(char mot[], int i, int j)
    {
    	char* partie = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
    	int k = 0;
     
    	for (k = i; k <= j; k++)
    	{
    		partie[k-i] = mot[k];
    	}
     
    	return partie;
    	free(partie);
    }
    A part que ça fasse un jeu de mots avec le nom de la variable, ça marchera comme il faut? Je pensais que return signifiait que ce qui suivait n'était pas pris en compte...


    EDIT: idem pour partOfSpeech() alors?
    "Les hommes et les femmes qui, sans bouger de leur bureau ou de leur bibliotheque, sans développer leur puissance corporelle et leurs infinies dimensions, parviennent, par une opération de la conscience, à une tristesse pessimiste qui se pretend lucide ne font que constater, sans le savoir, que toute identification du multiple de la vie à la vacuite de la conscience mène inévitablement à ce pessimisme et cette impuissance."

    extrait de "La fragilité" de Benasayag

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par mikhailo Voir le message
    Merci du conseil ^^

    Donc en fait, si j'écris:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    char* extractPart(char mot[], int i, int j)
    {
    	char* partie = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
    	int k = 0;
     
    	for (k = i; k <= j; k++)
    	{
    		partie[k-i] = mot[k];
    	}
     
    	return partie;
    	free(partie);
    }
    A part que ça fasse un jeu de mots avec le nom de la variable, ça marchera comme il faut? Je pensais que return signifiait que ce qui suivait n'était pas pris en compte...
    T'as pas compris - Faut libérer la zone "partie" une fois que tu n'en as plus besoin. c.a.d. après l'avoir utilisée et non dans la fonction. Un truc du style

    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
    ...
    ...
    char *toto;
    ...
    toto=extractPart(..., ..., ...);
    if (toto == NULL)
    {
        // Erreur malloc - Cas à gérer 
        // Se terminera probablement par l'arrêt de cette fonction
    }
    ... <je travaille avec toto>
    ... <je travaille avec toto>
    ... <je travaille avec toto>
    ... <je travaille avec toto>
     
    free(toto);
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  10. #10
    Membre régulier Avatar de mikhailo
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    78
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 78
    Points : 75
    Points
    75
    Par défaut
    Alors, j'ai essayé:

    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
    char* extractPart(char mot[], int i, int j, char partie[])
    {
    	int k = 0;
     
    	for (k = i; k <= j; k++)
    	{	
    		partie[k-i] = mot[k];
    	}
    	printf("partie = %s\n", partie);
    	return partie;
    }
     
     
     
     
     
    /* Puis, dans la fonction chercheAmbiguite: */
    {
    .
    .
    .
    char* partie = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
    .
    .
    .
    deux appels à extractMot;
    .
    .
    .
    free(partie);
    .
    .
    .
    }

    Ce qui est mieux, si j'ai bien compris. En revanche, du coup ma fonction extractPart ne marche plus, car la variable partie contient à chaque fois les affectations précédentes, et du coup quand on y met un mot plus court, on "voit" dépasser derrière la fin du mot le plus long que l'on a utilisé avant, par ex en faisant une recherche sur "porcin", ça me donne avec un printf à l'intérieur de extractMot:

    partie = p
    partie = orcin
    partie = pocin
    partie = rcinn
    partie = pornn
    partie = cinnn
    partie = porcn
    partie = inrcn
    partie = porci
    partie = norci
    partie = porcin
    partie = porcin
    partie = porcin
    partie = orcinn
    partie = pocinn
    partie = rcinnn
    partie = pornnn
    partie = cinnnn
    partie = porcnn
    partie = inrcnn
    partie = porcin
    partie = norcin
    partie = porcin
    partie = porcin
    partie = porcin
    partie = orcinADSL
    partie = pocinADSL
    partie = rcinADSLL
    partie = pornADSLL
    partie = cinADSLLL
    partie = porcDSLLL
    partie = inADSLLLL
    partie = porciLLLL
    partie = nADSLLLLL

    Il faut que je trouve un moyen de reinitialiser partie à chaque appel... Est-ce que ce serait propre de faire:

    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
    void chercheAmbiguite(char mot[], char exception1[], char exception2[])
    {
    	int i = 0;
    	int length = strlen(mot);
    	char* part1;
    	char* part2;
    	char* partie = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
     
    	for (i = 0; i < length; i++)
    	{
    		partie = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
    		part1 = extractPart(mot, 0, i, partie);
    		free(partie);
    		partie = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
    		part2 = extractPart(mot, i+1, length-1, partie);
    		free(partie);
     
    		if ((strcmp(part1, exception1) != 0) && (strcmp(part1, exception2) != 0) && (strcmp(part2, exception1) != 0) && (strcmp(part2, exception2) != 0))
    		{
    /*
    			printf("%s %s\n", part1, part2);
    */
    			if ((rechercheDichotomique(part1) != "*error") && (strlen(part1) > 1))
    			{
    				if ((rechercheDichotomique(part2) != "*error") && (strlen(part2) > 1))
    				{
    					printf("%s %s   <<< concaténation initiale\n%s %s   <<< partitionnement alternatif; URL équivoque valable!\n", exception1, exception2, part1, part2);
    				}
    			}
    		}
    	}
    }


    EDIT: on ne dirait pas que ce soit une solution, car ça me segfaulte assez rapidement... Que faire alors?
    "Les hommes et les femmes qui, sans bouger de leur bureau ou de leur bibliotheque, sans développer leur puissance corporelle et leurs infinies dimensions, parviennent, par une opération de la conscience, à une tristesse pessimiste qui se pretend lucide ne font que constater, sans le savoir, que toute identification du multiple de la vie à la vacuite de la conscience mène inévitablement à ce pessimisme et cette impuissance."

    extrait de "La fragilité" de Benasayag

  11. #11
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par mikhailo Voir le message
    EDIT: on ne dirait pas que ce soit une solution, car ça me segfaulte assez rapidement... Que faire alors?
    Non, ce n'est pas mieux car part1 (respectivement part2) pointe sur la zone mémoire allouée pour partie (puisque tu ne fais que retourner l'adresse de partie. Lorsque tu libères la mémoire allouée avec free(partie), c'est mémoire n'est plus utilisable que ce soit depuis partie ou depuis part1. L'appel strcmp(part1, exception1) est donc incorrect.

    Il faut libérer la mémoire lorsque tu ne l'utilises plus du tout, pas lorsque tu n'utilises plus un des pointeurs contenant l'adresse de cette mémoire.

  12. #12
    Membre régulier Avatar de mikhailo
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    78
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 78
    Points : 75
    Points
    75
    Par défaut
    Hum, je crois avoir trouvé une solution....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char* extractPart(char mot[], int i, int j, char partie[])
    {
    	partie = strndup(mot+i, j+1);
     
    	return partie;
    }
    En sachant que partie est donc malloc-ée dans la fonction appelant extractPart, et free ensuite.







    Ce qui donne un code "tout propre":


    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
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    #define _GNU_SOURCE
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
     
     
    #define DICO "lefff-2.1.txt"
    #define TAILLE_LIGNE_MAX 200
     
     
     
    /*Déclaration des variables globales relatives à rechercheDichotomique */
    FILE* FICHIER_DICO;
    char* LIGNE_RENVOYEE;
     
    /*Déclaration des variables globales relatives à concateneMots */
    char* CONCATENATION;
     
     
     
    /*
    Extrait une partie du mot, comprise entre les indices i et j. On suppose:
    i < j;
    j <= (strlen(mot) - 1);
    */
     
    char* extractPart(char mot[], int i, int j, char partie[])
    {
    	partie = strndup(mot+i, j+1);
     
    	return partie;
    }
     
     
     
     
     
     
    /*
    Fonction concaténant en un mot deux mots prix en argument.
    */
    char* concateneMots(char mot1[], char mot2[])
    {
    	strcpy(CONCATENATION, mot1);
    	strcat(CONCATENATION, mot2);
     
    	return CONCATENATION;
    }
     
     
     
     
     
     
     
     
     
     
     
     
    int nombreLignes(char chemin[])
    {
    	int nombre_lignes = 0;
    	char c[200];
     
    	FILE* fichier = NULL;
    	fichier = fopen(chemin, "r");
     
    	while (fgets(c, TAILLE_LIGNE_MAX, fichier) != NULL)
    	{
    		nombre_lignes++;
    	}
     
    	fclose(fichier);
    	return nombre_lignes;
    }
     
     
     
     
     
     
    /*
    accoutrée		v	[pred='accoutrer_____1<obj:(sn),objde:(de-sn),suj:(par-sn)>',cat=v,@passive,@être,@Kfs]
    */
     
    char* partOfSpeech(char ligne_dico[], char classeg[])
    {
    	char* mot = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
    	int* nombre = (int*)malloc(TAILLE_LIGNE_MAX * sizeof(int));
    	classeg = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
    	sscanf(ligne_dico, "%s %d %s", mot, nombre, classeg);
    	if (*nombre == 0)
    	{
    		sscanf(ligne_dico, "%s %s", mot, classeg);
    	}
     
    	free(nombre);
    	free(mot);
    	return classeg;
    }
     
    /*
    verbe, adjectif, pronom, nom commun, (nom propre), adverbe, *conjonction de coordinations, *préposition
    v	adj	pro		nc	np		adv	coo				prep
    conjonction de subordination,			determinant,
    csu(afin que)			cld(lui)	det
     
    */
     
     
     
     
    /*
    Fonction qui extrait le mot de la ligne du dictionnaire correspondante.
    */
    char* getMot(char ligne_dico[], char mot_recup[])
    {
    	sscanf(ligne_dico, "%s", mot_recup);
    	return mot_recup;
    }
     
     
     
     
     
     
     
     
     
     
    char* rechercheDichotomique(char mot[])
    {
    	int stop = 0;
    	int position_current = 0;
    	int n = 2;
    	int signe = 1;
    	int etape = 0;
    	int modificateur = 0;
    	int k = 0;
    	int l = 0;
    	int leng = 0;
    	char aux[TAILLE_LIGNE_MAX];
    	char mot_lu[TAILLE_LIGNE_MAX];
    	char c[1];
     
    	fseek(FICHIER_DICO, 0, SEEK_END);
    	int taille_dico = ftell(FICHIER_DICO);
    	fseek(FICHIER_DICO, 0, SEEK_SET);
     
    	while (stop != 1)
    	{
    		if (position_current%2 == 0)
    		{
    			modificateur = taille_dico/n;
    		}
    		else
    		{
    			modificateur = ((int)taille_dico/(n)) + 1;
    		}
     
    		if (modificateur < k)
    		{
    			modificateur = k;
    		}
     
    		position_current = position_current + signe*(modificateur);
     
    		if (position_current < 0)
    		{
    			position_current = position_current + modificateur - l;
    		}
     
     
    		etape = etape + 1;
    		n = n * 2;
     
    		fseek(FICHIER_DICO, position_current, SEEK_SET);
    		l = 0;
     
    		while((c[0] = fgetc(FICHIER_DICO)) != '\n')
           		{	
        			fseek(FICHIER_DICO, -2, SEEK_CUR);
    			l = l + 1;
     
    		}
    		position_current = position_current - l;		
     
     
    		fscanf(FICHIER_DICO, "%s", mot_lu);
    		leng = strlen(mot_lu);
    /*
    		printf("etape %d, position dans le fichier: %d, pas de la recherche: %d\n", etape, position_current, modificateur);
    		printf("mot lu: %s\n", mot_lu);
    		printf("comparaison entre %s et '%s': %d\n\n", mot_lu, mot, strcmp(mot_lu, mot));
    */		
    		if (etape > 25)
    		{
    			fseek(FICHIER_DICO, 0, SEEK_SET);
    			return "*error";
    		}
    		if (strcmp(mot_lu, mot) == 1)
    		{
    			signe = -1;
    			k = 24;
    			while ((c[0] = fgetc(FICHIER_DICO)) != '\n')
    			{
    				k = k + 1;
    			}
     
    			fseek(FICHIER_DICO, -k, SEEK_CUR);
     
    		}
    		if (strcmp(mot_lu, mot) == -1)
    		{
    			signe = 1;
    			k = 24;
    			while ((c[0] = fgetc(FICHIER_DICO)) != '\n')
    			{
    				k = k + 1;
    			}
     
    			fseek(FICHIER_DICO, -k, SEEK_CUR);
     
    		}		
    		if (strcmp(mot_lu, mot) == 0)
    		{
    /*			printf("%s = %s, recherche terminee en %d etapes!\n", mot_lu, mot, etape);*/
    			stop = 1;
    		}
    	}	
     
    	fseek(FICHIER_DICO, -leng, SEEK_CUR);
    	fgets(aux, TAILLE_LIGNE_MAX, FICHIER_DICO);
    	strcpy(LIGNE_RENVOYEE, aux);
    /*	
    	printf("taille du fichier: %d octets\n", taille_dico);
    */	
    	fseek(FICHIER_DICO, 0, SEEK_SET);
    	return LIGNE_RENVOYEE;
    }
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    void chercheAmbiguite(char mot[], char exception1[], char exception2[])
    {
    	int i = 0;
    	int length = strlen(mot);
    	char* part1;
    	char* part2;
    	char* partie = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
     
    	for (i = 0; i < length; i++)
    	{
    		part1 = extractPart(mot, 0, i, partie);
    		part2 = extractPart(mot, i+1, length-1, partie);
     
    		if ((strcmp(part1, exception1) != 0) && (strcmp(part1, exception2) != 0) && (strcmp(part2, exception1) != 0) && (strcmp(part2, exception2) != 0))
    		{
    /*
    			printf("%s %s\n", part1, part2);
    */
    			if ((rechercheDichotomique(part1) != "*error") && (strlen(part1) > 1))
    			{
    				if ((rechercheDichotomique(part2) != "*error") && (strlen(part2) > 1))
    				{
    					printf("%s %s   <<< concaténation initiale\n%s %s   <<< partitionnement alternatif; URL équivoque valable!\n", exception1, exception2, part1, part2);
    				}
    			}
    		}
    	}
    	free(partie);
    }
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    int main(int argc, char ** argv)
    {	
     
    	if (argc != 2)
    	{
    		printf("Un seul mot en argument à la fois, merci.\n");
    		return 0;
    	}
     
    	int i = 0;
    	int nombre_lignes;
    	char* result;
    	char* result2;
    	char ligne_lue[TAILLE_LIGNE_MAX];
    	char* mot_recup = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
     
    /*Affectation des variables relatives à rechercheDichotomique */	
    	FICHIER_DICO = fopen(DICO, "r");
    	LIGNE_RENVOYEE = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
     
    /*Affectation des variables relatives à concateneMots */
    	CONCATENATION = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
     
    /*Déclaration des variables relatives à partOfSpeech */
    	char* classeg = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
     
     
    	result = rechercheDichotomique(argv[1]);
     
    	if (strcmp(result, "*error") != 0)
    	{
    		result2 = partOfSpeech(result, classeg);
    		printf("%s", result);
    		printf("Classe grammaticale = %s\n", result2);
    	}
    	else
    	{
    		printf("Le mot propose ne fait pas partie du dictionnaire :'-)\n");
    	}
     
    	nombre_lignes = nombreLignes(DICO);	
     
    	FILE* fichier = NULL;
    	fichier = fopen(DICO, "r");
     
    	for (i = 0; i < nombre_lignes; i++)
    	{
    		fgets(ligne_lue, TAILLE_LIGNE_MAX, fichier);
    		getMot(ligne_lue, mot_recup);
    		if (i%1000 == 0)
    		{
    			printf("%dème mot lu = %s\n", i, mot_recup);
    		}
    		chercheAmbiguite(concateneMots(argv[1], mot_recup), argv[1], mot_recup);
    		chercheAmbiguite(concateneMots(mot_recup, argv[1]), mot_recup, argv[1]);
    	}
    	printf("Recherche terminée! :'-)\n");
    	fclose(FICHIER_DICO);
    	fclose(fichier);
    	free(LIGNE_RENVOYEE);
    	free(CONCATENATION);
    	free(classeg);
    	return 0;
    }

    Ou du moins, je ne crois pas avoir encore de pertes de mémoire... Reste à faire les tests sur le résultat de malloc et fopen, mais si c'est le seul problème que vous voyez, je serai déjà super content ^^
    "Les hommes et les femmes qui, sans bouger de leur bureau ou de leur bibliotheque, sans développer leur puissance corporelle et leurs infinies dimensions, parviennent, par une opération de la conscience, à une tristesse pessimiste qui se pretend lucide ne font que constater, sans le savoir, que toute identification du multiple de la vie à la vacuite de la conscience mène inévitablement à ce pessimisme et cette impuissance."

    extrait de "La fragilité" de Benasayag

  13. #13
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par mikhailo Voir le message
    Ce qui donne un code "tout propre":


    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
     
     
    /*Déclaration des variables globales relatives à concateneMots */
    char* CONCATENATION;
     
     
    /*
    Fonction concaténant en un mot deux mots prix en argument.
    */
    char* concateneMots(char mot1[], char mot2[])
    {
    	strcpy(CONCATENATION, mot1);
    	strcat(CONCATENATION, mot2);
     
    	return CONCATENATION;
    }
    Ou du moins, je ne crois pas avoir encore de pertes de mémoire... Reste à faire les tests sur le résultat de malloc et fopen, mais si c'est le seul problème que vous voyez, je serai déjà super content ^^
    Je crains de te décevoir... mais CONCATENATION (que tu remplis allègrement) n'est pas alloué. De plus, inutile de le renvoyer puisque cette variable est connue de tout le programme.

    Et hum... les variables globales c'est le mal.

    Ptite question: quel est le but de ce programme (pour qu'on puisse mieux t'aider) ???
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  14. #14
    Membre régulier Avatar de mikhailo
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    78
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 78
    Points : 75
    Points
    75
    Par défaut
    Hum... J'essaierai de trouver une solution plus élégante, mais sinon, si, CONCATENATION est alloué dans le main, comme tous ses amis =)
    "Les hommes et les femmes qui, sans bouger de leur bureau ou de leur bibliotheque, sans développer leur puissance corporelle et leurs infinies dimensions, parviennent, par une opération de la conscience, à une tristesse pessimiste qui se pretend lucide ne font que constater, sans le savoir, que toute identification du multiple de la vie à la vacuite de la conscience mène inévitablement à ce pessimisme et cette impuissance."

    extrait de "La fragilité" de Benasayag

  15. #15
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Citation Envoyé par mikhailo Voir le message
    Hum... J'essaierai de trouver une solution plus élégante, mais sinon, si, CONCATENATION est alloué dans le main, comme tous ses amis =)
    En fait, je pense que tu gagnerais plus de temps en reprenant ton programme depuis le début et en tentant de le concevoir proprement dès le départ. Cela ne signifie pas que tu ai mal codé dès le départ, mais tu es parti avec des notions faussées, et tu cherches (c'est bien légitime) à patcher le programme existant pour le rendre conforme aux normes. À mon avis, tu vas au devant de gros problèmes : ton code va devenir de plus en plus compliqué et tu vas finir par ne plus être capable de le maintenir.

  16. #16
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par mikhailo Voir le message
    Hum... J'essaierai de trouver une solution plus élégante, mais sinon, si, CONCATENATION est alloué dans le main, comme tous ses amis =)
    Arf, c'est là le problème des globales. On ne sait pas qui les modifie ni quand elles sont modifiées ou alors faut réexaminer à chaque fois tout le code => tu comprends que ce ne soit pas maintenable (comme le dit Obsidian)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  17. #17
    Membre régulier Avatar de mikhailo
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    78
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 78
    Points : 75
    Points
    75
    Par défaut
    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
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    #define _GNU_SOURCE
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
     
     
    #define DICO "lefff-2.1.txt"
    #define TAILLE_LIGNE_MAX 200
     
     
     
     
     
    /*
    Extrait une partie du mot, comprise entre les indices i et j. On suppose:
    i < j;
    j <= (strlen(mot) - 1);
    */
     
    char* extractPart(char mot[], int i, int j, char partie[])
    {
    	partie = strndup(mot+i, j+1);
     
    	return partie;
    }
     
     
     
     
     
     
    /*
    Fonction concaténant en un mot deux mots prix en argument.
    */
    char* concateneMots(char mot1[], char mot2[], char concatenation[])
    {
    	strcpy(concatenation, mot1);
    	strcat(concatenation, mot2);
     
    	return concatenation;
    }
     
     
     
     
     
     
     
     
     
     
     
     
    int nombreLignes(char chemin[])
    {
    	int nombre_lignes = 0;
    	char c[200];
     
    	FILE* fichier = NULL;
    	fichier = fopen(chemin, "r");
     
    	while (fgets(c, TAILLE_LIGNE_MAX, fichier) != NULL)
    	{
    		nombre_lignes++;
    	}
     
    	fclose(fichier);
    	return nombre_lignes;
    }
     
     
     
     
     
     
    /*
    accoutrée		v	[pred='accoutrer_____1<obj:(sn),objde:(de-sn),suj:(par-sn)>',cat=v,@passive,@être,@Kfs]
    */
     
    char* partOfSpeech(char ligne_dico[], char classeg[])
    {
    	char* mot = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
    	int* nombre = (int*)malloc(TAILLE_LIGNE_MAX * sizeof(int));
     
    	sscanf(ligne_dico, "%s %d %s", mot, nombre, classeg);
    	if (*nombre == 0)
    	{
    		sscanf(ligne_dico, "%s %s", mot, classeg);
    	}
     
    	free(nombre);
    	free(mot);
    	return classeg;
    }
     
    /*
    verbe, adjectif, pronom, nom commun, (nom propre), adverbe, *conjonction de coordinations, *préposition
    v	adj	pro		nc	np		adv	coo				prep
    conjonction de subordination,			determinant,
    csu(afin que)			cld(lui)	det
     
    */
     
     
     
     
    /*
    Fonction qui extrait le mot de la ligne du dictionnaire correspondante.
    */
    char* getMot(char ligne_dico[], char mot_recup[])
    {
    	sscanf(ligne_dico, "%s", mot_recup);
    	return mot_recup;
    }
     
     
     
     
     
     
     
     
     
     
    char* rechercheDichotomique(char mot[], FILE* dictionnaire, char ligne_renvoyee[])
    {
    	int stop = 0;
    	int position_current = 0;
    	int n = 2;
    	int signe = 1;
    	int etape = 0;
    	int modificateur = 0;
    	int k = 0;
    	int l = 0;
    	int leng = 0;
    	char aux[TAILLE_LIGNE_MAX];
    	char mot_lu[TAILLE_LIGNE_MAX];
    	char c[1];
     
    	fseek(dictionnaire, 0, SEEK_END);
    	int taille_dico = ftell(dictionnaire);
    	fseek(dictionnaire, 0, SEEK_SET);
     
    	while (stop != 1)
    	{
    		if (position_current%2 == 0)
    		{
    			modificateur = taille_dico/n;
    		}
    		else
    		{
    			modificateur = ((int)taille_dico/(n)) + 1;
    		}
     
    		if (modificateur < k)
    		{
    			modificateur = k;
    		}
     
    		position_current = position_current + signe*(modificateur);
     
    		if (position_current < 0)
    		{
    			position_current = position_current + modificateur - l;
    		}
     
     
    		etape = etape + 1;
    		n = n * 2;
     
    		fseek(dictionnaire, position_current, SEEK_SET);
    		l = 0;
     
    		while((c[0] = fgetc(dictionnaire)) != '\n')
           		{	
        			fseek(dictionnaire, -2, SEEK_CUR);
    			l = l + 1;
     
    		}
    		position_current = position_current - l;		
     
     
    		fscanf(dictionnaire, "%s", mot_lu);
    		leng = strlen(mot_lu);
    /*
    		printf("etape %d, position dans le fichier: %d, pas de la recherche: %d\n", etape, position_current, modificateur);
    		printf("mot lu: %s\n", mot_lu);
    		printf("comparaison entre %s et '%s': %d\n\n", mot_lu, mot, strcmp(mot_lu, mot));
    */		
    		if (etape > 25)
    		{
    			fseek(dictionnaire, 0, SEEK_SET);
    			return "*error";
    		}
    		if (strcmp(mot_lu, mot) == 1)
    		{
    			signe = -1;
    			k = 24;
    			while ((c[0] = fgetc(dictionnaire)) != '\n')
    			{
    				k = k + 1;
    			}
     
    			fseek(dictionnaire, -k, SEEK_CUR);
     
    		}
    		if (strcmp(mot_lu, mot) == -1)
    		{
    			signe = 1;
    			k = 24;
    			while ((c[0] = fgetc(dictionnaire)) != '\n')
    			{
    				k = k + 1;
    			}
     
    			fseek(dictionnaire, -k, SEEK_CUR);
     
    		}		
    		if (strcmp(mot_lu, mot) == 0)
    		{
    /*			printf("%s = %s, recherche terminee en %d etapes!\n", mot_lu, mot, etape);*/
    			stop = 1;
    		}
    	}	
     
    	fseek(dictionnaire, -leng, SEEK_CUR);
    	fgets(aux, TAILLE_LIGNE_MAX, dictionnaire);
    	strcpy(ligne_renvoyee, aux);
    /*	
    	printf("taille du fichier: %d octets\n", taille_dico);
    */	
    	fseek(dictionnaire, 0, SEEK_SET);
    	return ligne_renvoyee;
    }
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    void chercheAmbiguite(char mot[], char exception1[], char exception2[], FILE* dictionnaire, char ligne_renvoyee[])
    {
    	int i = 0;
    	int length = strlen(mot);
    	char* part1;
    	char* part2;
    	char* partie = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
     
    	for (i = 0; i < length; i++)
    	{
    		part1 = extractPart(mot, 0, i, partie);
    		part2 = extractPart(mot, i+1, length-1, partie);
     
    		if ((strcmp(part1, exception1) != 0) && (strcmp(part1, exception2) != 0) && (strcmp(part2, exception1) != 0) && (strcmp(part2, exception2) != 0))
    		{
    /*
    			printf("%s %s\n", part1, part2);
    */
    			if ((rechercheDichotomique(part1, dictionnaire, ligne_renvoyee) != "*error") && (strlen(part1) > 1))
    			{
    				if ((rechercheDichotomique(part2, dictionnaire, ligne_renvoyee) != "*error") && (strlen(part2) > 1))
    				{
    					printf("%s %s   <<< concaténation initiale\n%s %s   <<< partitionnement alternatif; URL équivoque valable!\n", exception1, exception2, part1, part2);
    				}
    			}
    		}
    	}
    	free(partie);
    }
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    int main(int argc, char ** argv)
    {	
     
    	if (argc != 2)
    	{
    		printf("Un seul mot en argument à la fois, merci.\n");
    		return 0;
    	}
     
    	int i = 0;
    	int nombre_lignes;
    	char* result;
    	char* result2;
    	char ligne_lue[TAILLE_LIGNE_MAX];
    	char* mot_recup = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
     
    /*Affectation des variables relatives à rechercheDichotomique */
    	FILE* FICHIER_DICO;	
    	FICHIER_DICO = fopen(DICO, "r");
    	char* LIGNE_RENVOYEE = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
     
    /*Affectation des variables relatives à concateneMots */
    	char* CONCATENATION = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
     
    /*Déclaration des variables relatives à partOfSpeech */
    	char* classeg = (char*)malloc(TAILLE_LIGNE_MAX * sizeof(char));
     
     
    	result = rechercheDichotomique(argv[1], FICHIER_DICO, LIGNE_RENVOYEE);
     
    	if (strcmp(result, "*error") != 0)
    	{
    		result2 = partOfSpeech(result, classeg);
    		printf("%s", result);
    		printf("Classe grammaticale = %s\n", result2);
    	}
    	else
    	{
    		printf("Le mot propose ne fait pas partie du dictionnaire :'-)\n");
    	}
     
    	nombre_lignes = nombreLignes(DICO);	
     
    	FILE* fichier = NULL;
    	fichier = fopen(DICO, "r");
     
    	for (i = 0; i < nombre_lignes; i++)
    	{
    		fgets(ligne_lue, TAILLE_LIGNE_MAX, fichier);
    		getMot(ligne_lue, mot_recup);
    		if (i%1000 == 0)
    		{
    			printf("%dème mot lu = %s\n", i, mot_recup);
    		}
    		chercheAmbiguite(concateneMots(argv[1], mot_recup, CONCATENATION), argv[1], mot_recup, FICHIER_DICO, LIGNE_RENVOYEE);
    		chercheAmbiguite(concateneMots(mot_recup, argv[1], CONCATENATION), mot_recup, argv[1], FICHIER_DICO, LIGNE_RENVOYEE);
    	}
     
    	printf("Recherche terminée! :'-)\n");
     
    	fclose(FICHIER_DICO);
    	fclose(fichier);
    	free(LIGNE_RENVOYEE);
    	free(CONCATENATION);
    	free(classeg);
    	return 0;
    }

    Hum²... Voilà, j'ai modifié le code encore. Maintenant tout ce qu'il faut est déclaré dans le main, et les fonctions se passent les pointeurs en paramètres en cascade. Et ça compile! Et ça marche comme c'est censé marcher!!
    "Les hommes et les femmes qui, sans bouger de leur bureau ou de leur bibliotheque, sans développer leur puissance corporelle et leurs infinies dimensions, parviennent, par une opération de la conscience, à une tristesse pessimiste qui se pretend lucide ne font que constater, sans le savoir, que toute identification du multiple de la vie à la vacuite de la conscience mène inévitablement à ce pessimisme et cette impuissance."

    extrait de "La fragilité" de Benasayag

  18. #18
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Citation Envoyé par mikhailo Voir le message
    Quant aux mauvaises habitudes, eh bien, en fait ça ne vient pas de Java. Je suis en licence d'info, mais j'y suis entré par équivalence, et je n'ai jamais vraiment fait d'info avant, donc j'ai appris à faire du C au premier semestre... donc mea culpa pour mes maladresses =)
    Aucun problème ! Ce n'était pas une critique, de toutes façons. C'est une question générique que l'on est amené à poser souvent depuis l'explosion du Java, qui est un bon langage par ailleurs, mais qui pose des problèmes à ceux qui veulent ensuite « remonter » vers le C.

    Citation Envoyé par mikhailo Voir le message
    Hum²... Voilà, j'ai modifié le code encore. Maintenant tout ce qu'il faut est déclaré dans le main, et les fonctions se passent les pointeurs en paramètres en cascade. Et ça compile! Et ça marche comme c'est censé marcher!!
    Bravo à toi ! Mais comme nous sommes puristes, voici encore quelques remarques. Ci-dessous, les avertissements que j'obtiens à la compilation :

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ gcc -pedantic -ansi -W -Wall -o fichierglobal fichierglobal.c
    
    fichierglobal.c: In function ‘rechercheDichotomique’:
    fichierglobal.c:144: attention : ISO C90 forbids mixed declarations and code
    fichierglobal.c: In function ‘chercheAmbiguite’:
    fichierglobal.c:276: attention : comparison with string literal results in unspecified behavior
    fichierglobal.c:278: attention : comparison with string literal results in unspecified behavior
    fichierglobal.c: In function ‘main’:
    fichierglobal.c:311: attention : ISO C90 forbids mixed declarations and code
    fichierglobal.c:321: attention : ISO C90 forbids mixed declarations and code
    fichierglobal.c:345: attention : ISO C90 forbids mixed declarations and code

    Les « mixed declarations and code » proviennent du fait qu'en principe, toutes les variables locales utilisées doivent être déclarées en début de bloc (accolades) avant la première instruction. C99 lève cette limitation, mais l'usage veut que ce principe soit toujours respecté en C.

    Par contre, « comparison with string literal », ça c'est une faute, qui se trouve ici :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    193         if (etape > 25)
    194         {
    195             fseek(dictionnaire, 0, SEEK_SET);
    196             return "*error";
    197         }
    
    …
    276             if ((rechercheDichotomique(part1, dictionnaire, ligne_renvoyee) != "*error") && (strlen(part1) > 1))
    277             {
    278                 if ((rechercheDichotomique(part2, dictionnaire, ligne_renvoyee) != "*error") && (strlen(part2) > 1))
    279                 {
    280                     printf("%s %s   <<< concaténation initiale\n%s %s   <<< partitionnement alternatif; URL équivoque valable!\n", exception1, exception2, part1, part2);
    281                 }
    282             }

    Tu ne peux pas comparer directement des chaînes avec « != » et « == ». Ça, tu le sais déjà, puisque tu fais des strcmp() à d'autres endroits. Ton code ne fonctionne que parce que ton compilateur est capable de reconnaître qu'il s'agit de la même chaîne, et de ne l'inscrire qu'une seule fois dans le fichier objet. Les pointeurs sont donc les mêmes des deux côtés et la comparaison devient valide, mais tu ne peux absolument pas t'y fier !

    La meilleure façon d'indiquer qu'un pointeur retourné par une fonction est invalide est de renvoyer NULL. Et cela, tu as parfaitement le droit de le vérifier avec les opérateurs de comparaison.

    Une fois ces détails réglés, tu auras un programme qui marche et qui ne déclenche plus d'avertissement même avec les flags. C'est un énorme progrès, certes, mais cela ne signifie pas encore qu'il est bien conçu. Il se peut tout-à-fait que des bugs intermittents apparaissent bien que le code soit syntaxiquement correct, et tu vas connaître les joies du déboguage.

  19. #19
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par mikhailo Voir le message
    En revanche, qu'entends-tu par non respect de const-correctness?
    Le fait de déclarer const les objets (surtout les tableaux et éléments pointés) qui n'ont pas de raisons d'être modifiés. Ce qui permet entre autres :
    • De détecter certaines erreurs d'inattention (je modifie la source la source plutôt que la destination).
    • D'utiliser des objets non modifiables (en particulier les chaînes littérales) en guise de paramètres de fonction. Et d'éviter ainsi certaines erreurs :


    C:\Data\projet\test_DVP\main.c|25|error: assignment makes pointer from integer without a cast|
    C:\Data\projet\test_DVP\main.c|196|error: return discards qualifiers from pointer target type|
    C:\Data\projet\test_DVP\main.c|343|error: passing arg 1 of `nombreLignes' *

  20. #20
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par mikhailo Voir le message

    Hum²... Voilà, j'ai modifié le code encore. Maintenant tout ce qu'il faut est déclaré dans le main, et les fonctions se passent les pointeurs en paramètres en cascade. Et ça compile! Et ça marche comme c'est censé marcher!!
    Obsidian a fait quelques remarques, je vais te faire les miennes...

    1) dans la fonction partOfSpeech, tu fais des malloc de zones à taille fixes. Autant les remplacer par des tableaux. Pareil pour la fonction chercheAmbiguite
    2) les éléments en majuscules sont généralement réservés aux #define
    3) la fonction concateneMot peut être remplacée par sprintf et devient alors inutile

    Mais bon, c'est du détail. Sinon je suis très heureux de tes efforts pour suivre nos conseils. Bravo à toi !!!
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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