[C] Récupération de valeurs

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

  • Votes
  • Date
  • Date décroissante
  1. 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
    1. 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?
      1. Modérateur
        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
        1. Modérateur
          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