[C]Probleme avec une structure ...

Probleme avec une structure ... [C] - C++ - Programmation

Marsh Posté le 18-01-2003 à 21:27:02    

J'ai un fichier qui contient ce type de données:
 

Code :
  1. 212.83.187.188 - - [01/Apr/2001:00:08:47 +0200] "GET /~luke/archi/message.html HTTP/1.1" 200 3519 "-" "Mozilla/4.0 (compatible; MSIE 5.0; Windows 2000; DigExt)"
  2. 212.154.187.111 - - [01/Apr/2001:00:08:48 +0200] "GET /~luke/archi/archive.css HTTP/1.1" 200 714 "http://www.google.fr/~luke/archi/message.html" "Mozilla/4.0 (compatible; MSIE 5.0; Windows 2000; DigExt)"....................,etc....


 
J'ai besoin de les traiter, et pour cela je pense utiliser une structure de la façon suivante:
 
pour stoker l'IP, la date, l'heure, et la page consultée.
 
 
Comment faut-il faire pour stoker l'IP ki est au debut du fichier dans la structure, la date ki se triuve dans le milieu du fichier et ainsi de suite ??
 
MERCI - le tout uniquement en C.


Message édité par FabienM le 19-01-2003 à 11:08:08
Reply

Marsh Posté le 18-01-2003 à 21:27:02   

Reply

Marsh Posté le 19-01-2003 à 15:16:35    

UP

Reply

Marsh Posté le 19-01-2003 à 15:21:16    

man fgets
man sscanf

Reply

Marsh Posté le 19-01-2003 à 17:31:10    

Oui mais le probleme est pour saisir cette partie par exemple qui est au milieu d'autre données.

Code :
  1. "GET /~luke/archi/message.html

Reply

Marsh Posté le 19-01-2003 à 18:21:46    

Ben une fois que t'as lu ta date, tu fscanf jusqu'à retrouver un caractère ", j'vois pas trop où est le prob  :heink:


---------------
[ Canon EOS 30D ] (Grip + Canon 50mm f/1.4 + Canon 18-55mm USM + Tamron 70-300mm Di LD Macro)  [Galerie perso]
Reply

Marsh Posté le 19-01-2003 à 21:46:04    

FabienM a écrit :

Oui mais le probleme est pour saisir cette partie par exemple qui est au milieu d'autre données.

Code :
  1. "GET /~luke/archi/message.html




 
ba en matter ce que tu as filer plus haut ca a pas l'air tres compiquer si ton fichier est organiser en ligne c a dire une ligne =  
 

Citation :

212.83.187.188 - - [01/Apr/2001:00:08:47 +0200] "GET /~luke/archi/message.html HTTP/1.1" 200 3519 "-" "Mozilla/4.0 (compatible; MSIE 5.0; Windows 2000; DigExt)"


 
donc tu fais une lecture dans un tableau ( pour le ligne a ligne tu fais fgets ou si tu connais la taille de chaque ligne voir l'ami fread) ensuite tu as ca dans un tableau tu analyse des que tu trouve le premier : " tu stock la chaine juska trouver le prochain " et la tu aurais dans un autre tableau la chaine souhaiter

Reply

Marsh Posté le 23-01-2003 à 03:36:50    

Faciiile !

Code :
  1. struct record{
  2. unsigned short ip[4];
  3. char dateheure[28];
  4. char url[512];
  5. }rcd;
  6. //lire une ligne
  7. fscanf(fich, "%hi.%hi.%hi.%hi - - [%[^]]] \"%[^\"]\"%*[\n]\n", &rcd.ip[0], &rcd.ip[1], &rcd.ip[2], &rcd.ip[3], rcd.dateheure, rcd.url);
  8. //%hi //short
  9. // - - [ //ignorer espace, tiret...
  10. //%[abc] //chaîne ne pouvant contenir que des a, b, ou c.
  11. //%[^abc] //chaîne pouvant contenir tout (espace compris), sauf des a, b, ou c.
  12. //%[^]] //chaîne terminée par ] exclu
  13. //\" //ignorer un "
  14. //%[^\"] //chaîne terminée par " exclu
  15. //%*[\n] //lire jusqu'au retour à la ligne (exclu), sans stocker (*)
  16. //\n  //ignorer un retour à la ligne


Avec ça, tu devrais pouvoir affiner les détails.
Sinon, montres la définition de la structure que tu veux remplir.
 
 
Si les largeurs sont immuables, on peut aussi jouer du fgets, strchr, strstr, memcpy et '\0'.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 24-01-2003 à 19:28:46    

Bah en faite la structure sera de la forme suivante:
 

Code :
  1. struct record{
  2. unsigned short ip[4];
  3. char date[28];
  4. char heure[8];
  5. char url[512];


 
J'vais reflechir sur ce ke tu m'a donnée...
Merci!

Reply

Marsh Posté le 25-01-2003 à 00:37:47    

Ça pourrait être comme ça:

Code :
  1. struct record{ 
  2. unsigned char ip[4];
  3. char date[12]; //11+1 pour le \0, 28 était trop
  4. char heure[9]; //8 +1 pour le \0, 8  était pas asser
  5. char url[512]; //char *url= allocation serait plus civilisé
  6. }rcd;
  7. char test[]= "212.83.187.188 - - [01/Apr/2001:00:08:47 +0200] \"GET /~luke/archi/message.html HTTP/1.1\" 200 3519 \"-\" \"Mozilla/4.0 (compatible; MSIE 5.0; Windows 2000; DigExt)\"";
  8. int temp[4];
  9. sscanf(test, //remplacer par 'fscanf(fich,' quand ça marche
  10. "%i.%i.%i.%i" //ip
  11. " - - ["
  12. "%11[^:]" //date (or "%11c" with char date[11])
  13. ":"         //sep
  14. "%8s"     //hour (or "%8c" with char heure[8])
  15. " "         //sep
  16. "%*[^]]"    //sep: hour shift (ignored)
  17. "] "        //sep
  18. "\"GET "    //sep: url header
  19. "%511s"      //url
  20. "%*[\n]"  //everything till end of line (ignored)
  21. "\n"        //sep: end of line
  22. , &temp[0], &temp[1], &temp[2], &temp[3], rcd.date, rcd.heure, rcd.url);
  23. rcd.ip[0]= (unsigned char)temp[0];
  24. rcd.ip[1]= (unsigned char)temp[1];
  25. rcd.ip[2]= (unsigned char)temp[2];
  26. rcd.ip[3]= (unsigned char)temp[3];


Ce découpage est possible car le compilateur joint les chaînes littérales adjacentes.
Les nombres dans le format sont optionnels, ils permettent d'éviter les débordements.
L'alternative "%c" lit exactement le nombre demandé, sans ajouter '\0'.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 28-01-2003 à 15:45:23    

Merci mais j'ai reussi à modifier la structure comme j'en ai besoin.
 
Le probleme qui se pose maintenant, est pour saisir plusieur ligne ds le fichier, car j'ai inseré la commande fscanf ds une boucle while mais sans succes... pas moyen de saisir plusieur ligne...
 
Comment pourrais-je faire ?? j'ai pensé stocker tous le contenu ds un tableau de structure afin de pouvoir les retraiteés par la suite...mais je ne sais pas trop comment m'y prendre.

Reply

Marsh Posté le 28-01-2003 à 15:45:23   

Reply

Marsh Posté le 29-01-2003 à 00:39:08    

Je vois pas trop le problème...

Code :
  1. struct record rtab[512];
  2. FILE* f=fopen(...);
  3. int i=0
  4. for(;;){
  5. int nbChampsLus= fscanf(f,/*le gros boxon*/, rtab[i].ip[0],...);
  6. if(nbChampsLus != 8) //le nombre de champs à lire
  7.  break;
  8. ++i;
  9. }
  10. //ici i indique le nombre de structures lues en entier


Message édité par Musaran le 29-01-2003 à 00:40:24

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 29-01-2003 à 21:07:46    

euh, tu pourrais commencer par un tableau de string que tu remplis à coups de fgets,  
puis tu attaques ces lignes une à une en memoire à coups de sscanf...


---------------
Angel Eyes, j'en raffole tous les matins... :pt1cable:  
Reply

Marsh Posté le 29-01-2003 à 21:16:40    

Angel_Eyes a écrit :

euh, tu pourrais commencer par un tableau de string que tu remplis à coups de fgets,  
puis tu attaques ces lignes une à une en memoire à coups de sscanf...
 

si les E/S déjà bufferisées ralentissent vraiment ton programme (voir ton profiler et le temps system (ca existe ca sous windows)), tu peux effectivement envisager mapper ton fichier en mémoire si ton log fait 80mo.
 
mais dans le cas de ce problème, comme le traitement est fait ligne par ligne et que je ne connais pas de fonctions capables de lire plusieurs lignes en un seul appel systeme, il faut faire confiance au buffer des FILE* et a ton systeme, et continuer comme tu fait.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed