[C] Récupération de valeurs

Fermé
Brique - 24 mai 2006 à 18:51
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 - 24 mai 2006 à 21:20
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

crabs Messages postés 908 Date d'inscription lundi 18 avril 2005 Statut Membre Dernière intervention 3 août 2008 507
24 mai 2006 à 19:23
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
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
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
24 mai 2006 à 21:01
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
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
24 mai 2006 à 21:20
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