dadevil Posté(e) le 12 juin 2005 Partager Posté(e) le 12 juin 2005 Bonjour à tous, voilà, j'ai un projet à rendre demain, mais j'ai mon code qui foire et à force de passer et repasser dessus, je comprends pu gd chose, de +, les quelques notions de C que j'ai eu l'année dernière se révèle insuffisante pour terminer correctement, donc si qqn aurait la gentilesse de trouver où ça cloche, je lui en serai très reconnaissant. je dois écrire un programme capable de: lire un fichier txt contenant des adresses mails formatées de la sorte: toto@tutu.com titi@tata.com abcdefgh@ijklmnop.net donc une adresse mail par ligne. le programme doit: - faire un classement alphabétique des adresses - éliminer les adresses redondantes - créer un nouveau fichier ne comportant que les domaines, classés par ordre alphabétique, en supprimant aussi les redondances. Pour le passage du format mail au format domaine; j'ai réussi à écrire un programme qui le fait sans problème, en prenant tt ds le 1er fichier & en sauvegardant le tout dans un nouveau, donc ma fonction intermédiaire est remplie. Là où je bloque, c'est dans le tri alphabétique & la suppression des redondances. Voici la partie intermédiaire qui fonctionne pour le passage du format mail au domaine: #include <stdlib.h> #include <string.h> #include <stdio.h> int main() { FILE *e; FILE *s; int *i; char *ligne; char *str1; char *str2 = "@", *ptr; e=fopen("blacklist1.txt","r"); s=fopen("domainelist.txt","w"); while (fscanf(e,"%s", ligne) ==1) { str1 = ligne; ptr = strstr(str1, str2); ptr++; i = ptr; fprintf(s, "%s\n", i); } } Ensuite ma première partie sur le tri alphabétique, qui ne fonctionne pas: #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { typedef struct maillon { char mail[255]; struct maillon *suivant; } maillon; FILE *f; FILE *f2; char nom[255]; char ligne[255]; maillon *liste; maillon *parcours; maillon *prec; maillon *new; int i; char vide[256]; vide[0]=""; vide[1]="\0"; f=fopen("trimail.txt", "r"); if (f == NULL) printf("Erreur d'ouverture du fichier trimail.txt \n"); else{ liste = (maillon *)malloc(1*sizeof(maillon)); // liste->mail = (char *)malloc(1*sizeof(char)); printf("test1\n"); //strcpy(liste->mail, vide); printf("test2\n"); liste->suivant = NULL; liste->mail[0]='z'; parcours = liste; new= (maillon *)malloc(1*sizeof(maillon)); new->suivant = NULL; // new->mail = (char *)malloc(1*sizeof(char)); printf("test3\n"); while(fscanf (f, "%s", nom) != EOF) { printf("boucle\n"); fscanf(f,"%s", ligne); strcpy(new->mail,ligne); i = strcmp(ligne,liste->mail); if(i<0) {printf("premier\n"); new->suivant = liste; liste = new; }else{ printf("suite\n"); prec = liste; parcours = liste->suivant; if (parcours!=NULL) { i = strcmp(parcours->mail,ligne); while ((parcours!= NULL) && (i<0)){ printf("ok\n"); prec = parcours; parcours = parcours->suivant; i = strcmp(parcours->mail,ligne); } } if (parcours == NULL){ printf("null\n"); new->suivant = parcours; prec->suivant = new; }else{ printf("pas null\n"); prec->suivant = new; new->suivant = parcours;} } } parcours = liste; f2=fopen("tonfichier2.txt","w"); if(f2==NULL) { printf ("erreur\n"); } else { /* while (parcours!=NULL) */ {fprintf(f2,parcours->mail); printf("écrit\n"); fprintf(f2,"\n"); /* parcours=parcours->suivant;} */ } fclose(f2); if (parcours == NULL){ printf("null"); } while(parcours != NULL){ printf(parcours->mail); parcours = parcours->suivant; } } } } et enfin la 3e partie, sur la suppression des redondances, qui elle aussi bug, parce que je n'arrive pas à la terminer, notamment le passage en liste chaînée et la suppression de la ligne en i2 qd i1=i2 #include <stdio.h> #include <stdlib.h> int main() { char mail [] []; int i=0; int i2; int ilast; int cp; x=fopen("fichier2.txt", "r"); y=fopen("domainesfinal.txt", "w"); do { fscanf(x,"%s", mail[i++]); } while (fscanf(x,"%s", mail) ==1) /* passage dans une liste chaînée */ /* comparaison */ i=0; while ( i1<ilast ) { while ( i2<ilast ) { cp = strcmp (i1,i2); if (cp == NULL) {// supprimer la ligne en i2 (mais je ne sais pas la manip } i2++; } i1++; } fprintf(y,"%s", mail[i++]); } Merci à ceux qui trouveront les solutions. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sentinel Posté(e) le 12 juin 2005 Partager Posté(e) le 12 juin 2005 <OFF-TOPIC> Mince le C c'est parti loin... Par contre, un petit cut -d@ -f2 <mails.txt | uniq | sort > domaines.txt suffit pour extraire, dans l'ordre et sans doublons, tous les noms de domaine... C'est à vous dégoûter de programmer en C hein . (quoique, un petit exec("script.sh")... lol). </OFF-TOPIC> Bon j'espère qu'une âme bienveillante t'aidera à résoudre ton problème. Courage ! Lien vers le commentaire Partager sur d’autres sites More sharing options...
dadevil Posté(e) le 12 juin 2005 Auteur Partager Posté(e) le 12 juin 2005 Personne n'a d'idée? Lien vers le commentaire Partager sur d’autres sites More sharing options...
LePhasme Posté(e) le 12 juin 2005 Partager Posté(e) le 12 juin 2005 t'es obligé d'utiliser les listes chainées ? Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sentinel Posté(e) le 12 juin 2005 Partager Posté(e) le 12 juin 2005 Ben sans connaître le nombre d'emails dans le fichier, c'est dur de faire un tableau... à moins de fixer arbitrairement une limite maximale, très élevée... mais on comprend bien les problèmes que pose cette solution. Remarque, au lieu d'utiliser une liste chaînée, autant utiliser un arbre binaire, au moins les résultats seront directement triés. Lien vers le commentaire Partager sur d’autres sites More sharing options...
dadevil Posté(e) le 12 juin 2005 Auteur Partager Posté(e) le 12 juin 2005 le nombre d'adresses mails ainsi que leur longueur sont complètement aléatoire, donc ce n'est pas vrmt possible d'utiliser un tableau l'arbre binaire, késako? arriverais-tu à donner un algo utilisant ce principe & accessoiremet supprimant aussi les redondances? @sentinel: au fait pour ton code de tout à l'heure, les fonctions sort & uniq sous nux, c'est prog en C, et jpeux te dire, k'elles sont très longues Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sentinel Posté(e) le 12 juin 2005 Partager Posté(e) le 12 juin 2005 Oui, sort & uniq sont écrites en C, comme la plupart des outils gnu. Ce que je voulais dire, c'est que si j'avais à trier un fichier de mails aujourd'hui, j'utiliserais un petit script shell au lieu d'écrire un énorme programme C... Si ce programme est dans le cadre d'études (études d'info, ou un simple module info dans une autre formation), ça se comprend d'imporser le langage. Par contre, pour l'arbre binaire, si tu l'as vu en cours tu dois savoir l'utiliser, sinon, ben utilise les outils à ta disposition actuellement, à savoir les listes chaînées. Je ne suis pas sûr qu'un prof apprécie qu'on utilise des techniques qu'il n'a pas encore enseignées... Surtout si elles sont mal utilisées. En effet, les arbres sont plus compliqués que les listes chaînées, donc si tu as déjà des problèmes à manipuler celles-ci... Pour ton programme, l'algo me paraît simple : piocher un mail dans le fichier, parcourir toute la liste chaînée pour vérifier s'il est déjà dedans; si le mail n'est pas déjà connu, on l'ajoute à la liste. Une fois que tous les mails sont lus, il suffit de créer un tableau de taille égale à celle de la liste, et d'appliquer un algo de tri pour extraire, dans l'ordre alphabétique, les mails de la liste chaînée et les placer dans le tableau... Ou, mieux encore, tirer parti de la nature dynamique des listes chaînées pour jouer avec le chaînage des éléments, ce qui permet de trier la liste elle-même, et d'éviter la création d'un tableau. Lien vers le commentaire Partager sur d’autres sites More sharing options...
dadevil Posté(e) le 12 juin 2005 Auteur Partager Posté(e) le 12 juin 2005 Effectivement, c'est dans le cadre d'études. Le problème c'est que c'est pas des études d'infos, et que le langage C, on a appris que les bases l'année dernière. Et encore, quand on est arrivé au listes chaînées, le prof a pas été capable de nous apprendre qqc qui fonctionne, encore moins avec un algo de tri Cette année, on a aucun cours d'info & de prog en C, et le prof qui a donné ce sujet n'était même pas au courant... Vive la fac! Ca a été la lutte pour avoir les sujets & encore + pour voir le prof, ça fait 2 semaines que je planche là dessus, le pb est que c'est à rendre pour demain & finalement jme galère + que prévu. Donc si une âme charitable pouvait m'aider avant quje pète un cable, ce serait sympa. Je suis en train de me dégouter du C. De tte façon, l'année prochaine je me barre de cette fac bidon & j'irai en License info sur Lille, malheureusement en attendant ça m'avance pas . je craque, j'ai encore à réviser pour mes exams qui tombent dans 4jours et j'ai tjs pas eu le temps à cause de ce satané prog. Lien vers le commentaire Partager sur d’autres sites More sharing options...
MissZaza Posté(e) le 12 juin 2005 Partager Posté(e) le 12 juin 2005 Salut, Y'a un truc que je pige pas. Tu lis tes adresses mail qui sont dans un fichier, si tu en as une par ligne, tu peux très bien en déduire le nombre d'adresses. Tu lis ton fichier, tu incrémentes un compteur en même temps et tu auras le nombre de lignes. Si tu ne veux pas relire ton fichier par la suite, tu crées une liste chainée qui contiendra toutes tes adresses. Tu peux ensuite construire un tableau de char[256] et recopier les adresses de ta liste dans ton tableau. Ce sera nettement plus facile de classer un tableau par ordre alphabétique qu'une liste chainée. Lien vers le commentaire Partager sur d’autres sites More sharing options...
dadevil Posté(e) le 12 juin 2005 Auteur Partager Posté(e) le 12 juin 2005 Salut,Y'a un truc que je pige pas. Tu lis tes adresses mail qui sont dans un fichier, si tu en as une par ligne, tu peux très bien en déduire le nombre d'adresses. Tu lis ton fichier, tu incrémentes un compteur en même temps et tu auras le nombre de lignes. Si tu ne veux pas relire ton fichier par la suite, tu crées une liste chainée qui contiendra toutes tes adresses. Tu peux ensuite construire un tableau de char[256] et recopier les adresses de ta liste dans ton tableau. Ce sera nettement plus facile de classer un tableau par ordre alphabétique qu'une liste chainée. J'ai justement pensé à ce petit tweak. J'ai bouclé la conversion en domaines & la suppression des redondances est elle aussi OK. Là, je refais l'algo de tri, pour l'instant j'ai: int main(){ FILE * fi; struct tableau{ char *mail; }; int nblignes=0; /* test comptage de lignes */ while (fscanf(fi, "%s", mail) ==1) nblignes++; /* boucle tableau */ for(i=0;i<nblignes;i++) { je bloque dans la suite du code pr le moment Lien vers le commentaire Partager sur d’autres sites More sharing options...
MissZaza Posté(e) le 12 juin 2005 Partager Posté(e) le 12 juin 2005 et pourquoi tu fais pas plutôt: int nblignes=0; char ligne[256]; /* test comptage de lignes */ while (fscanf(fi, "%s", ligne) != EOF) nblignes++; /* déclaration du tableau */ char ** tableau = new char *[nblignes]; for (i=0; i<nblignes; i++) tableau = new char[256]; /* Relecture du fichier */ i=0; rewind(f); while (fscanf(fi, "%s", ligne) != EOF) { tableau = ligne; i ++; } merde je me suis plantée, tu fais du C, le new c'est pas bon, il faut faire malloc. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Patator Posté(e) le 12 juin 2005 Partager Posté(e) le 12 juin 2005 [HUMOUR] On peut aussi faire un appel système à la fonction du shell, c'est du C, non? [/HUMOUR] Lien vers le commentaire Partager sur d’autres sites More sharing options...
MissZaza Posté(e) le 12 juin 2005 Partager Posté(e) le 12 juin 2005 ah oui, et pour la relecture, il faut faire strcpy(tableau, ligne); j'ai écrit un peu vite... Lien vers le commentaire Partager sur d’autres sites More sharing options...
dadevil Posté(e) le 13 juin 2005 Auteur Partager Posté(e) le 13 juin 2005 [HUMOUR]On peut aussi faire un appel système à la fonction du shell, c'est du C, non? [/HUMOUR] et qd on doit porter ça sous win? Lien vers le commentaire Partager sur d’autres sites More sharing options...
mogwai93 Posté(e) le 13 juin 2005 Partager Posté(e) le 13 juin 2005 et qd on doit porter ça sous win? Une fois que tu as un code qui fonctionne (Unix ou Ms-Dos) le portage sous Windows se fait rapidement (sauf si appels à des methodes propres à l'OS) il te faut le code de base (Creation d'une fenetre simple) : /* Creation of a simple Windows API program */ #include <windows.h> /* Declare Windows procedure */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); /* Make the class name into a global variable */ char szClassName[ ] = "WindowsApp"; int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { HWND hwnd; /* This is the handle for our window */ MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use Windows's default color as the background of the window */ wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; /* Register the window class, and if it fails quit the program */ if (!RegisterClassEx (&wincl)) return 0; /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ "Windows App", /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 544, /* The programs width */ 375, /* and height in pixels */ HWND_DESKTOP, /* The window is a child-window to desktop */ NULL, /* No menu */ hThisInstance, /* Program Instance handler */ NULL /* No Window Creation data */ ); /* Make the window visible on the screen */ ShowWindow (hwnd, nFunsterStil); /* Run the message loop. It will run until GetMessage() returns 0 */ while (GetMessage (&messages, NULL, 0, 0)) { /* Translate virtual-key messages into character messages */ TranslateMessage(&messages); /* Send message to WindowProcedure */ DispatchMessage(&messages); } /* The program return-value is 0 - The value that PostQuitMessage() gave */ return messages.wParam; } /* This function is called by the Windows function DispatchMessage() */ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) /* handle the messages */ { case WM_DESTROY: PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; default: /* for messages that we don't deal with */ return DefWindowProc (hwnd, message, wParam, lParam); } return 0; } et rajouter une interface et les interactions (boutons ==> evenements à coder dans la methode WindowProcedure Qqs exemples sur : http://www.foosyerdoos.fsnet.co.uk/ ou alors les modeles dans Devcpp sinon pose une question sur un des pbs que tu pourrais rencontrer bonne chance Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.