Bonjour,
Est-ce qu'il existe une fonction en C permettant de rediriger le pointeur dans un fichier une ligne plus haut svp ?
Merci
Bonjour,
Est-ce qu'il existe une fonction en C permettant de rediriger le pointeur dans un fichier une ligne plus haut svp ?
Merci
Non, rien en standard.
Tu peux lorsque tu es sur la ligne précédente faire un ftell() pour stocker la position et pouvoir t'y replacer ultérieurement avec
fseek(...,...,SEEK_SET)
ah ok merci
je vais aller voir de plus près ftell et fseek
J'ai vu qu'il existe d'autres fonctions similaires :
fsetpos et fgetpos
Donc je ne sais pas quoi choisir entre fsetpos et fgetpos ou ftell et fseek
Quelle est la meilleure alternative pour analyser des fichiers très gros (>16 000 000 lignes) svp ?
merci
16 000 000 de lignes ? lol
Tu fait quoi comme simulation la ?
prise de traces sur la Gi et export de wireshark en full expand pour analyser certaines infos ...
et encore j'ai découpé le fichier en 5 sinon l'export txt fait 4go et plus de 80 000 000 de lignes -_-
Un algo dichotomique + fseek + ftell + une petite exploration pour avoir le début de ligne avec fgetc marche très bien..
hmmmm
sinon est-ce qu'il existe des fonctions permettant simplement de soit lire un fichier txt à l'envers soit de récrire un fichier txt mais dans l'autre sens :
faire des fgets et des inserts afin que chaque ligne soit insérer au début du fichier ?
merci
peut-on savoir ce que tu veux faire ?
A moins de réécrire le fichier, on ne peut pas "insérer" une ligne dans un fichier eistant...
en fait le txt est fait pas bloc et dans certains blocs j'ai une information que je voudrais prendre !
Voici un exemple de bloc :
Tous les blocs commencent par le même entête et sont séparés par une ligne vide
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 No. Time Protocol Lenght Source Destination Port_S Port_D Info 1 0.000000000 HTTP 650 10.148.6.170 93.188.128.20 novation http GET /css/genealogie_en_ligne.css?20080407 HTTP/1.1 Frame 1 (650 bytes on wire, 650 bytes captured) Arrival Time: Apr 3, 2009 14:23:29.404058000 [Time delta from previous captured frame: 0.000000000 seconds] [Time delta from previous displayed frame: 0.000000000 seconds] [Time since reference or first frame: 0.000000000 seconds] Frame Number: 1 Frame Length: 650 bytes Capture Length: 650 bytes [Frame is marked: False] [Protocols in frame: eth:ip:tcp:http] [Coloring Rule Name: HTTP] [Coloring Rule String: http || tcp.port == 80] Ethernet II, Src: JuniperN_0b:e4:1f (00:05:85:0b:e4:1f), Dst: Cisco_f9:34:00 (00:14:1b:f9:34:00) Destination: Cisco_f9:34:00 (00:14:1b:f9:34:00) Address: Cisco_f9:34:00 (00:14:1b:f9:34:00) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) Source: JuniperN_0b:e4:1f (00:05:85:0b:e4:1f) Address: JuniperN_0b:e4:1f (00:05:85:0b:e4:1f) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) Type: IP (0x0800) Internet Protocol, Src: 10.148.6.170 (10.148.6.170), Dst: 93.188.128.20 (93.188.128.20) Version: 4 Header length: 20 bytes Differentiated Services Field: 0x48 (DSCP 0x12: Assured Forwarding 21; ECN: 0x00) 0100 10.. = Differentiated Services Codepoint: Assured Forwarding 21 (0x12) .... ..0. = ECN-Capable Transport (ECT): 0 .... ...0 = ECN-CE: 0 Total Length: 636 Identification: 0x2666 (9830) Flags: 0x04 (Don't Fragment) 0... = Reserved bit: Not set .1.. = Don't fragment: Set ..0. = More fragments: Not set Fragment offset: 0 Time to live: 127 Protocol: TCP (0x06) Header checksum: 0xe3bf [correct] [Good: True] [Bad : False] Source: 10.148.6.170 (10.148.6.170) Destination: 93.188.128.20 (93.188.128.20) Transmission Control Protocol, Src Port: novation (1322), Dst Port: http (80), Seq: 1, Ack: 1, Len: 596 Source port: novation (1322) Destination port: http (80) Sequence number: 1 (relative sequence number) [Next sequence number: 597 (relative sequence number)] Acknowledgement number: 1 (relative ack number) Header length: 20 bytes Flags: 0x18 (PSH, ACK) 0... .... = Congestion Window Reduced (CWR): Not set .0.. .... = ECN-Echo: Not set ..0. .... = Urgent: Not set ...1 .... = Acknowledgment: Set .... 1... = Push: Set .... .0.. = Reset: Not set .... ..0. = Syn: Not set .... ...0 = Fin: Not set Window size: 16384 Checksum: 0x08a7 [correct] [Good Checksum: True] [Bad Checksum: False] Hypertext Transfer Protocol GET /css/genealogie_en_ligne.css?20080407 HTTP/1.1\r\n Request Method: GET Request URI: /css/genealogie_en_ligne.css?20080407 Request Version: HTTP/1.1 User-Agent: Opera/9.64 (Windows NT 5.1; U; fr) Presto/2.1.1\r\n Host: media.genealogie.com\r\n Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1\r\n Accept-Language: fr,en-GB;q=0.9,en;q=0.8\r\n Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r\n Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0\r\n Referer: http://www.genealogie.com/v4/forums/recherches-genealogiques-la-double-nationalite-francaise-/-espagnole-comment-ca-se-passe-t106724-p1.html\r\n Connection: Keep-Alive\r\n \r\n
L'entête est :
et ce qui m'intéresse est :
Code : Sélectionner tout - Visualiser dans une fenêtre à part No. Time Protocol Lenght Source Destination Port_S Port_D Info
Ce que je fais est de parcourir ligne par ligne jusqu'à arriver sur une entête. Ensuite je prend la ligne suviante dans un buffer et je regarde si la première IP correspond à ce que j'ai en mémoire. Si oui, je parcours la suite jusqu'à arriver à "User-Agent" pour prendre la suite ou bien jusqu'à arriver soit à la fin du fichier soit à un autre bloc ou j'arrête et je recommence (chaque bloc ne contenant pas forcément un champs "User-Agent")
Code : Sélectionner tout - Visualiser dans une fenêtre à part User-Agent: Opera/9.64 (Windows NT 5.1; U; fr) Presto/2.1.1\r\n
Voici mon code actuel :
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 while (fgets(tempon,nb_max_char,value) != NULL) { if (strstr(tempon,"No.") != 0 && strstr(tempon,"Time") != 0 && strstr(tempon,"Protocol") != 0) //test d'entête, modifié plusieurs fois pour voir si le problème ne venait pas de là { fgets(tempon,nb_max_char,value); //si entête je prend la prochaine ligne avec les infos sscanf(tempon,"%s %s %s %s %s %s %s %s %[^\n]s",temp[0],duree,protocol,size_string,temp[1],temp[2],temp[3],temp[4],info); fgets(tempon2,nb_max_char,value); //je saute la ligne vide ensuite for (j=0;j<nb_ip_norme;j++) //comparaison de l'IP1 avec ma liste d'IP { if ((strcmp(temp[1],ip_tab_norme[j]) == 0) && (ip_norme_found[j] == 0)) //Si IP trouvé et pas déjà analysé { while (fgets(tempon,nb_max_char,value) != NULL) //on récupère la suite { if (strstr(tempon," User-Agent: ") != 0) //si on voit User Agent on prend la suite { sscanf(tempon,"%s %[^\n]s",temp[0],info); strcpy(user_agent_tab[j],info); ip_norme_found[j] = 1; break; } /*if (strstr(tempon,"No.") == NULL) { fgetpos (value, &position); } if (strstr(tempon,"No.") != 0) { fsetpos (value, &position); break; }*/ /*if (strcmp(tempon,"") == 0) { break; }*/ if (strlen(tempon) < 2) break; // ce sont les différents tests pour dire stop quand arrive à un nouveau bloc je sais pas lequel est mieux mais le problème viens sans doute de la. Si nouveau bloc on sort du while } break; // et on sort du for } } } }
Quel rapport avec les questions que tu as précédemment posées ?en fait le txt est fait pas bloc et dans certains blocs j'ai une information que je voudrais prendre !
Quel est ton problème avec le code que tu proposes ?....rediriger le pointeur dans un fichier une ligne plus haut
.... lire un fichier txt à l'envers soit de récrire un fichier txt mais dans l'autre sens :
Le rapport est qu'en arrivant sur une ligne contenant l'entête j'aimerais revenir une ligne en arrière et sortir de la boucle pour une nouvelle itération.
Le problème est que ma liste d'User-Agent que je récupère ne correspond pas aux IP ...
plusieurs problèmes :
- strstr retourne un pointeur. La comparaison doit donc se faire par rapport à NULL
- l'orthographe correcte est "tampon" et non "tempon"
- tes fgets intérieurs n'ont pas de tests pour savoir si ils ont réussi
- Pourquoi faire compliqué quand on peut faire simple ?
- Tu effectues une boucle de fgets sur les numéros d'IP déjà stockés... Problème de conception.
- Pourquoi vouloir sortir de la boucle en étant revenu en arrière ?
un morceau de code plus simple :
Mais il y a un truc que je comprend pas, c'est comment tu initialises ta liste de ips.
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 #define ENTETE 0 #define USER 1 #define OTHER 2 int TypeLigne ; int DoIt = 0 ; int nb_ip_norme = 0; while (fgets(tampon,nb_max_char,value) != NULL) { if ( strstr(tampon,"No. ") != NULL ) TypeLigne = ENTETE ; else if ( strstr(tampon,"User-Agent") != NULL ) TypeLigne = USER ; else TypeLigne = OTHER ; switch ( TypeLigne ) { case ENTETE : DoIt = 0 ; if ( fgets(tampon,nb_max_char,value) != NULL ) { sscanf(tampon,"%s %s %s %s %s %s %s %s %[^\n]s", temp[0],duree,protocol,size_string,temp[1], temp[2],temp[3],temp[4],info); for (j=0;j<nb_ip_norme;j++) { if ((strcmp(temp[1],ip_tab_norme[j]) == 0) && (ip_norme_found[j] == 0)) { DoIt = 1 ; break ; } } if ( DoIt ) { strcpy ( ip_tab_norme[nb_ip_norme], temp[1]); p_norme_found[nb_ip_norme] = 0; nb_ip_norme++ ; } } break ; case USER : if ( DoIt ) { sscanf(tampon,"%s %[^\n]s",temp[0],info); strcpy(user_agent_tab[nb_ip_norme-1],info); ip_norme_found[nb_ip_norme-1] = 1; DoIt = 0 ; } break ; default : break ; } }
Là je l'ai construite au vol, sauf que la comparaison du coup est fausse (le strcmp).
Ton problème de revenir en arrière vient du fait que tu peux retomber sur un bloc alors que tu cherches un User-Agent.
Il faut réorganiser ton code pour centraliser les tests qui identifient un bloc et un User-Agent.
Par exemple :
Naturellement, ce code n'est pas testé (je n'ai pas ce qu'il faut comme fichier et il faudrait ajouter un bon paquet de code et de définitions)
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 while (fgets(tempon,nb_max_char,value) != NULL) { int ipindex; // index de l'IP dans la table int unbloc ; // l'entête est trouvé int unagent ; // User-Agent est touvé unbloc = strstr(tempon,"No.") != NULL && strstr(tempon,"Time") != NULL && strstr(tempon,"Protocol") != NULL ; unagent = !unbloc && strstr(tempon,"User-Agent:") != NULL; if(unbloc) { //si entête je prend la prochaine ligne avec la 5ieme info (Source) fgets(tempon,nb_max_char,value); sscanf(tempon,"%*s %*s %*s %*s %s",temp[1]); // recherche si l'IP est dans la table et non analysé for (j=0, ipindex = -1;j<nb_ip_norme && ipindex<0;j++) if( strcmp(temp[1],ip_tab_norme[j]) == 0 && ip_norme_found[j] == 0) { ipindex = j; } } else if (unagent && ipindex>=0 ) { sscanf(tempon,"%*s %[^\n]s",info); strcpy(user_agent_tab[ipindex],info); ip_norme_found[ipindex] = 1; } }
[Grilled ]
Merci pour votre aide, je vais jeter un coup d'oeil aux codes !
-> souviron
J'ai regardé et testé ton code. Je crois avoir compris le principe et il est très intéressant. Si j'ai bien compris à chaque fois que tu rencontre un ENTETE tu mets à jour la donnée ce qui permet lorsqu'on rencontre un USER-AGENT de mettre l'info dans la bonne case !
Sinon quand je fais tourner -> erreur windows machin mémoire
Je pense qu'il y'a un problème d'indice dans :
et aussi
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 if ( DoIt ) { strcpy ( ip_tab_norme[nb_ip_norme], temp[1]); ip_norme_found[nb_ip_norme] = 0; nb_ip_norme++ ; }
Merci beaucoup pour cet algorithme
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 case USER : if ( DoIt ) { sscanf(tempon,"%s %[^\n]s",temp[0],info); strcpy(user_agent_tab[nb_ip_norme-1],info); ip_norme_found[nb_ip_norme-1] = 1; DoIt = 0 ; } break ;
ben le problème c'est que dans le code que tu as fourni on ne sait pas comment sont initialisées les variables nb_ip_norme et ip_tab_norme..
Comme je l'ai mentionné en bas de mon post précédent, là je faisait au vol mais le test de comparaison était faux, puisque je stockais en tentant de comparer à quelque chose qui à priori n'était pas défini (pour moi).
Il faudrait donc que tu nous dises comment tu intialisais..
En fait, nb_ip_norme stock un int avec le nombre d'IP trouvé correspondant aux paramètres.
J'ai refait tourner un coup avec ton algorithme et je trouve les mêmes résultats .... peut-être que le problème est ailleurs en fait -_-
Je vais revérifier tout ça !
Merci à souviron et diogene pour leur aide !!
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager