[C] Récupération de valeurs

Brique -  
lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   -
Bonjour,

je dois récupérer des IP provenant d'un traceroute comme dans l'exemple suivant et les stockées dans un tableau de char **

Exemple de fichier ou il faut récupérer les IP
 1  192.168.0.1  9.754 ms  9.461 ms  8.046 ms
 2  195.6.244.14  60.885 ms  48.924 ms  90.517 ms
 3  194.206.126.244  50.503 ms  48.97 ms  120.122 ms
 4  194.206.126.2  55.655 ms  52.213 ms  58.908 ms
 5  * * *
 6  208.213.229.130  588.303 ms  589.843 ms  589.611 ms
 7  208.213.229.129  599.564 ms  599.763 ms  600.749 ms
 8  208.213.229.226  629.167 ms  599.284 ms  599.383 ms
 9  157.130.34.217  642.326 ms  715.072 ms  653.724 ms
10  146.188.160.62  595.143 ms  590.433 ms  659.247 ms
11  146.188.160.181  649.863 ms  700.901 ms  617.067 ms
12  137.39.253.86  600.835 ms  599.379 ms  590.867 ms
13  192.48.96.9  607.071 ms  589.221 ms  603.156 ms


Voici le code que j'ai écrit.
Le problème est que n'obtiens pas ce qu'il faut en sortie.
J'obtiens ça en sortie
213.46.242.124


J'aurais besoin d'aide car je ne sais pas comment corriger cela.

Merci

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define F "fichier"

static void purge(FILE *fp)
{
   int c;
   while ((c = fgetc(fp)) != '\n' && c != EOF)
   {
   }
}

static void clean (char *s, FILE *fp)
{
   /* search ... */
   char *p = strchr (s, '\n'); /* <string.h> */
   if (p != NULL)
   {
      /* ... and kill */
      *p = 0;
   }
   else
   {
      purge (fp);
   }
}

int main()
{
   FILE *fp = fopen(F, "r");
   char **tab;
   int nb = 1, size = 1;
   char **pt;
   
   tab = malloc (nb * sizeof * tab);
   if(tab == NULL)
     {
       perror("erreur allocation\n");
       exit(1);
     }
   
   if (fp != NULL)
     {
       char line[BUFSIZ];
       
       while(fgets(line, sizeof line, fp) != NULL)
	 {
	   clean(line, fp);
	   char *p = strtok(line," ");
	   if (p != NULL)
	     {
	       p = strtok(NULL," ");
	       if (p != NULL)
		 { 
		   if(nb == size)
		     {
		       size *= 2;
		       
		       tab = realloc(tab, size * sizeof *tab);
		       if (tab == NULL)
			 {
			   perror("erreur allocation\n");
			   exit(1);
			 }
		     }
		   tab[nb-1] = malloc((strlen(p)+1) * sizeof * tab[nb-1]);
		   if (tab[nb-1] == NULL)
		     {
		       perror("erreur allocation\n");
		       exit(1);
		     }
		   strcpy(tab[nb-1],p);
		   
		   while(*p == " ")
		     p++;
		 }
	       
	       else
		 {
		   printf ("format error\n");
		   break;
		 }
	     }
	   else
	     {
	       printf ("format error\n");
	       break;
	     }
	 }
       fclose (fp), fp = NULL;
       tab[nb] = NULL;
     }
   else
     {
       perror (F);
     }
   
   for(pt = tab; *pt != NULL; pt++)
     printf("%s\n",*pt);
   
   return 0;
}

4 réponses

  1. crabs Messages postés 909 Statut Membre 507
     
    Salut,
    Après une lecture de ton code 2 problèmes :
    - i l n'y a pas d'incrémentation de nb
    - tab[nb] = NULL; peut causer un erreur car à la fin de la boucle nb peut
    être égal à size, le realloc se faisant en début de boucle.
    Si nb représente le nombre d'entrée non nulle de ton tableau (comme argc
    pour argv) il faut l'initialiser à 0 et pas à 1.

    Une autre remarque size *=2 pour ton realloc est une stratégie "ogre" au
    niveau de ta mémoire, adoptes une stratégie de type incrémentation par 16 ou
    plus (pour 1024 tu ajouterai 4ko à chaque realloc à ton tableau tab si tu es sur
    un OS 32 bits).

    A+, crabs
    0
  2. Brique
     
    Salut,

    avec les indications que tu as donné, j'obtiens maitenant les adresse IPs souhaités.

    J'aurais une autre question.
    J'ai écrit ce programme qui à partir d'une IP doit renvoier un tableau d'entier.
    Voici le Code :
    int *tabIP(char *chaine){
      int ip[4];
      int n;
    
      n = sscanf(chaine, "%d.%d.%d.%d", ip,ip+1,ip+2,ip+3);
      if(n != 4){
        printf("erreur\n");
        return NULL. 
      }
    return ip;
    }


    Le problème est que ce n'est pas correcte.
    Que faut-il modifier?
    0
  3. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Salut,

    si tu n'as besoin que du résultat tu peux utiliser une regex à la place des lignes de code que tu as écrit.

    https://www.commentcamarche.net/faq/911-regexp-recuperer-une-adresse-ip

    lami 20j
    0
  4. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,

    pour s'amuser
    #!/usr/bin/perl
    
    use warnings;use strict;
    my @ip;
    while (<DATA>){
      if ( /((?:\d{1,3}\.){3}\d{1,3})/){
        push @ip,$1;
      }
    }
    $"="\n";
    print "@ip\n";
    
    # après END sont les données à lire
    __END__
     1  192.168.0.1  9.754 ms  9.461 ms  8.046 ms
     2  195.6.244.14  60.885 ms  48.924 ms  90.517 ms
     3  194.206.126.244  50.503 ms  48.97 ms  120.122 ms
     4  194.206.126.2  55.655 ms  52.213 ms  58.908 ms
     5  * * *
     6  208.213.229.130  588.303 ms  589.843 ms  589.611 ms
     7  208.213.229.129  599.564 ms  599.763 ms  600.749 ms
     8  208.213.229.226  629.167 ms  599.284 ms  599.383 ms
     9  157.130.34.217  642.326 ms  715.072 ms  653.724 ms
    10  146.188.160.62  595.143 ms  590.433 ms  659.247 ms
    11  146.188.160.181  649.863 ms  700.901 ms  617.067 ms
    12  137.39.253.86  600.835 ms  599.379 ms  590.867 ms
    13  192.48.96.9  607.071 ms  589.221 ms  603.156 ms
    
    Le résultat
    [lamitest@localhost trash]$ perl ip_traceroute.pl
    192.168.0.1
    195.6.244.14
    194.206.126.244
    194.206.126.2
    208.213.229.130
    208.213.229.129
    208.213.229.226
    157.130.34.217
    146.188.160.62
    146.188.160.181
    137.39.253.86
    192.48.96.9
    

    lami20j

    P.S. j'ai utiliser \d à la place de [0-9] et aussi (?: ..) - paranthèses non capturantes à la place de () pour les 3 premiers octets
    0