Bonjour,

Ce script est un exercice demandé dans le cadre d'un cours en fac, ou on apprend le langage C. C'est d'ailleurs un exercice qui mélange C et un début d'implémentation façon "Lisp".
Il n'est utile de proposer une autre solution, je suis les directives établies par le prof qui a conçu ce cours, toute refonte du programme dans une tournure qui vous sied sera donc hors sujet.

J'ai juste une erreur de compilation lié à un transtypage que je n'arrive pas à remédier à la ligne 153 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
gcc -Wall -g cx17.6.c
cx17.6.c: Dans la fonction «*cons*»:
cx17.6.c:153:15: attention: l'affectation à «*void **» depuis «*idx*» {alias «*long unsigned int} transforme un entier en pointeur sans transtypage [-Wint-conversion]
  153 |    new -> car =  *ptr_car;
      |               ^
Le programme s'appuie de deux fichiers :
- un dénommé indexe-moi.texte (ou on met n'importe quel texte, j'ai copier-coller un passage de l'Odyssée d'Homère par ex)
- un fichier dénommé stoplist.data (ou on y trouve des articles tel que : le la l ce au aux leur du de des à il les

Hormis cette erreur de compilation, le programme renvoie ce que je veux. Le but est d'afficher par exemple :
accabler : 23
amis : 21
antre : 17
briser : 20
bœufs : 8
Calypso : 16
camps : 13
Car : 7
Ces : 8 10
chef : 1
colère : 22
comme : 3
connus : 10
conserver : 5
D : 23
Dans : 17 22
Destin : 18
Dieu : 9
dieux : 21
dis : 1
Déesse : 10
déité : 16
Déjà : 12
dévorèrent : 8
en : 7
enfant : 10
erra : 2
et : 5 9 15
exécrée : 12
Eût : 19
faits : 10
femme : 15
fit : 7
flamme : 17
flots : 13
fous : 8
fussent : 6
Grecs : 12
groupe : 7
....
Ce programme est donc un index lexicographique capable de lire un texte et d'en indexer chaque mot en référençant leurs numéros de ligne, la stop list permet de sélectionner des articles et pour les supprimer de l'index.
Est-ce que l'erreur de compilation parle à quelqu'un ?

Merci par avance, du coup de main.

Bonne journée.

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
 
#include <stdio.h> // pour FILE, stderr, les fontions stream, printf(), fprintf() et gets()
#include <stdlib.h> // pour exit()
#include <string.h> // pour strtok() et strdup()
#define DEBUG if (1) fprintf
 
//Déclaration
typedef char * str;
typedef long unsigned int idx;
typedef struct node {void *car; struct node *cdr;} node, *list;
typedef struct ndex{str mot; list refs;} ndex;
 
//Défintions et initialisations de variables globales
const str split_chars ="(., -;:'\t\n!<>)";	//Une séquence de caractères comportant des délimiteurs nécessaires à la fonction strtok()
 
enum{
	nil,		
	max_mots = 10000, 						//Nombre maximum de mots
	max_refs = 16,							//Nombre maximum de référence par mots
	max_ligne = 256, 						//Nnombre maximum de lignes dans le fichier
	max_stoplist= 13,						//Nombre maximum de mots dans la stoplist
	tampon = 32,							//Zone de mémoire temporaire nécessaire dans la fonction recuperer_stoplist()
	};
typedef enum {
	False,True} bool;	
idx mot_libre = 0;							//Variable qui indique la prochaine cellule vide du vecteur mots			
ndex mots[max_mots];
str mots_stoplist[max_stoplist];
 
//Les prototypes des fonctions :
void usage(str, str);
void indexe(str, idx);
int indice(str);
bool pareil(str, str);
void ajoute_mot(idx, str, idx);
void ajoute_ref(idx, idx);
void dump(idx);
FILE * ouvrir_fichier(const str);
void fermer_fichier(FILE *, str);
void recuperer_stoplist();
int compare(const void*, const void*);
list cons(void *car, list L);
void putlist(list);
 
int main (int argc, const str argv[]){
	// Cette fonction ouvre un fichier, ajoutes chaque mot dans un vecteur de mots 
	// en le reliant à ses références et son numéro de lignes
	if (argc != 2) 
		usage(argv[0], "Usage : <nom du programme> <nom du fichier>\n");
	FILE * flux = ouvrir_fichier(argv[1]);
	char ligne[max_ligne];
	idx x = 0;
	recuperer_stoplist();
	while (fgets(ligne, max_ligne, flux))
		indexe(ligne, ++x);
	fermer_fichier(flux, argv[1]);
	qsort(mots, mot_libre, sizeof(ndex), compare);
	dump(mot_libre);
	return 0;
}
 
int compare(const void *E1, const void *E2){
	return strcasecmp(* (char * const *) E1, * (char * const *) E2);
}
 
FILE * ouvrir_fichier(const str nom_fichier){ //Ouverture d'un fichier en mode lecture avec vérification
	FILE * fichier = fopen(nom_fichier, "r");
	if (!fichier) 
		usage(nom_fichier,"Echec lors de l'ouverture du fichier, consulter la documentation utilisateur\n");
	return fichier;
}
 
void fermer_fichier(FILE * flux, str nom_fichier){ // Fermeture d'un fichier avec vérification
if (fclose(flux))
		usage(nom_fichier, "Echec lors de la fermeture du fichier, consulter la documentation utilisateur\n");
}
 
void recuperer_stoplist(){ // Ouvre un fichier contenant la stoplist et enregister les mots dans un vecteur
	FILE * stoplist = ouvrir_fichier("stoplist.data");
	int lu;
	for (idx i = 0; lu != EOF; ++i){
		char sas[tampon];
		lu = fscanf(stoplist,"%s", sas);
		if (i > max_stoplist)
			usage("stoplist.data", "Le nombre maximum de mots autorisé est dépassé\n");
		mots_stoplist[i] = strdup(sas);
	}
	fermer_fichier(stoplist, "stoplist.data");
}
 
void usage(str nom_fichier, str message){ //Affiche un message d'erreur
	perror(nom_fichier);
	fprintf(stderr, message);
	exit(1);
}
 
void indexe(str ligne, idx ref){
	//Extrait les mots de l'argument ligne, si ils existent, 
	//vérifie si les mots existent dans le vecteur mots grâce à  indice(mot)
	//et envoie chaque mot soit vers la fonction ajoute_mot() 
	//ou soit vers ajoute_ref() suivant leur existance ou non dans les tables
	str mot = strtok(strdup(ligne), split_chars);
	while (mot){
		int x = indice(mot);
		if (x < 0) 
			ajoute_mot(mot_libre, mot, ref);
		else 
			ajoute_ref(x, ref);
		mot = strtok(NULL, split_chars);
	}
}
 
int indice(str mot){ //retourne l'indice d'un mot déja présent dans mots[maxmots] ou -1 s'il est inexistant.
	idx x;
	for (x = 0; mots[x].mot; ++x)
		if (pareil(mot, mots[x].mot)) 
			return x;
	return -1;
}
bool pareil(str x, str y){ 	// return Vraie que x et y sont similaire sinon retourne faux.
	return strcasecmp(x, y) ? False : True;}
 
 
void ajoute_mot(idx x, str mot, idx ref){ // ajoute le mot dans le vecteur mots à l'indice x correspondant
	for(int i = 0 ; i < max_stoplist; ++i){
		if (pareil(mot, mots_stoplist[i]))
			return;
	}
	mots[x].mot = mot;
	idx *ptr_ref = &ref;
	mots[x].refs = cons(ptr_ref, nil);
	++mot_libre;
}
 
void ajoute_ref(idx x, idx ref){ //Ajoute une référence
	idx * ptr_ref = &ref;
	//ajoute une référence dans la matrice refs[max_mots][max_ref]
if(mots[x].refs->car != ptr_ref) mots[x].refs = cons(ptr_ref, mots[x].refs);
}
 
void dump(idx k){
	// Affichage des mots, de leur lignes et du nombre de références associés
	idx x = 0;
	while(mots[x].mot){
		printf("%s :", mots[x].mot);
			putlist(mots[x].refs);
			printf("\n");
		++x; 
	}
}
 
list cons(void *car, list L){ // Implémentation d'un cons
	list new = malloc(sizeof(node));
	idx * ptr_car = car;
	if (!new) usage ("","cons : manque de RAM");
	 	new -> car =  *ptr_car;
		new -> cdr = L;
		return new;
}
 
void putlist(list L){ //Affichage d'une liste
	if (!L) return; //nil : fin de ligne
	putlist(L -> cdr);
	printf(" %li ", (idx) L -> car);
}