Conversion d'un string en adresse IP

Conversion d'un string en adresse IP - C++ - Programmation

Marsh Posté le 10-08-2005 à 17:00:37    

Bonjour à tous,
 
voilà je développe une application où l'utilisateur doit saisir des adresses ip. Le problème est de vérifier si l'adresse ip saisie est valide.
 
En gros, dés que l'utilisateur fait quelque chose du style 320.15.54.1 ou 255.255.1. je lui demande de resaisir le champ...
 
Y a t il une fonction toute faite qui existe en C++? J'ai fait des recherches mais j'ai rien trouvé... Au pire je peux le coder, ca doit pas être super difficile à faire...  
 
Merci pour vos réponses.
 
p1c0.

Reply

Marsh Posté le 10-08-2005 à 17:00:37   

Reply

Marsh Posté le 10-08-2005 à 17:15:02    

tu veux juste vérifier la saisie ? [:pingouino]

Reply

Marsh Posté le 10-08-2005 à 17:22:10    

theshockwave a écrit :

tu veux juste vérifier la saisie ? [:pingouino]


 
Ben oui pourquoi? Je veux être sûr que l'utilisateur a bien saisi une adresse ip...

Reply

Marsh Posté le 10-08-2005 à 17:25:34    

ben, dans ce cas, non, il n'y a rien de tout fait expressément pour ca ... Mais sinon, tu peux faire un gethostbyname sur ton ip sous forme de chaine et regarder si le résultat est valide (ca te retournera probablement un type d'erreur pour te l'indiquer, dans le cas où l'ip est malformée) ... J4ai pas vérifié, mais bon, réécrire ca, c'est rien, en temps : std::stringstream, tu envoies les données dans des entiers et tu testes les valeurs (et si le stringstream a bien pu remplir la valeur) et ca te dira si ton IP est ok
 
Edit : autre solution, plus adaptée pour ton cas : regexp ('parait qu'il y en a dans boost :o)


Message édité par theshockwave le 10-08-2005 à 17:26:19
Reply

Marsh Posté le 10-08-2005 à 17:34:47    

gethostbyname ne correspond pas à mon problème, elle est utilisée pour retrouver l'adresse ip d'une machine en fonction de son nom or moi j'ai déjà l'adresse ip...
 
Pour le std::stringstream, ca parait bien mais je ne maîtrise pas du tout les flux... Je vais me pencher la dessus.
 
Et boost, c'est quoi la licence? Parce que c'est pour une application commerciale..

Reply

Marsh Posté le 10-08-2005 à 17:50:09    

_p1c0_ a écrit :

gethostbyname ne correspond pas à mon problème, elle est utilisée pour retrouver l'adresse ip d'une machine en fonction de son nom or moi j'ai déjà l'adresse ip...


 
oups, pardon, c'est getaddrinfo qui t'intéresse, j'ai utilisé ca récemment et j'ai un peu confondu dans mon post précédent ...
 
(http://www.boost.org/more/license_info.html)
 
Edit : pôur te faciliter la tâche :

Citation :

the Boost license is not "viral": if you distribute your own code along with some Boost code, the Boost license applies only to the Boost code (and modified versions thereof); you are free to license your own code under any terms you like


Message édité par theshockwave le 10-08-2005 à 17:51:18
Reply

Marsh Posté le 10-08-2005 à 17:53:07    

Ok merci, j'essaye de coder ça avec les stringstream... Je crois que j'ai le plus dur, y a plus qu'a améliorer un peu tout ca et ca devrait marcher...
 
Tu préfèrerais quelle méthode toi?  

Reply

Marsh Posté le 10-08-2005 à 18:08:41    

bah, les regexp sont faites pour ce genre de traitements, notamment, donc bon, j'irais jeter un oeil à boost. D'un autre côté, c'est vrai qu'incorporer boost à une appli juste pour tester des ip ... [:petrus75] Si tu le fais avec des stringstreams, ce sera pas mal, hein :D

Reply

Marsh Posté le 10-08-2005 à 18:23:45    

Ca pourrait être bien avec les stringstream mais j'arrive pas à récupérer l'exception si c'est pas un entier que j'essaye de convertir..
 

Code :
  1. int test;
  2. string octet("ss" );
  3. try{
  4.   istringstream ss(octet);
  5. }catch(std::exception& e){
  6.   exit(0);
  7. }
  8. try{
  9.   ss >> std::dec >> test;
  10. }catch(exception& e){
  11.   exit(0);
  12. }


 
Et ca passe sans problème... Aucune exception n'est levée... Si vous pouviez m'éclairer un peu sur ce point..  :??:

Reply

Marsh Posté le 10-08-2005 à 18:31:28    

# }catch(exception& e){
#   exit(0);
 
 
foutage de gueule !

Reply

Marsh Posté le 10-08-2005 à 18:31:28   

Reply

Marsh Posté le 10-08-2005 à 18:44:35    

Taz a écrit :

# }catch(exception& e){
#   exit(0);
 
 
foutage de gueule !


 
Le exit(0) c'est juste pour mes tests. A la fin du programme, j'affiche une chaine de caractère, si elle ne s'affiche pas c'est qu'il est sorti avant. C'est peut être pas propre mais ca suffit pour les tests que je fais. De plus, j'avais mis un :
 

Code :
  1. cout <<e.what();


et ca n'affichait rien non plus!  :sarcastic:

Reply

Marsh Posté le 10-08-2005 à 18:44:57    

Taz a écrit :

# }catch(exception& e){
#   exit(0);
 
 
foutage de gueule !


 
Tu n'aurais pas voulu lui expliquer comment tester si la donnée a bien été remplie par le flux, par la même occasion ? :o

Reply

Marsh Posté le 10-08-2005 à 18:49:43    

vous voulez pas lire les "sujets utiles" de la cat C++ plutôt que de débiter des bêtises plus grosse que vous ?

Reply

Marsh Posté le 10-08-2005 à 20:21:14    

theshockwave a écrit :

Tu n'aurais pas voulu lui expliquer comment tester si la donnée a bien été remplie par le flux, par la même occasion ? :o


 
C'est vrai que cela aurait été plus intelligent de sa part...  :o  
 
Je vais faire quelques recherches supplémentaires, il est clair que je ne suis pas au point sur les flux. Maintenant, j'ai voulu aller au plus vite et c'est certainement la meilleure solution.  :sarcastic:

Reply

Marsh Posté le 10-08-2005 à 20:25:05    

man inet_pton
 
C'est pas le peine de faire des :o quand on sait pas faire de recherche :
 
http://forum.hardware.fr/hardwaref [...] 1250-1.htm
 
Je te t'explique pas comment faire une recherche pour savoir comment lire correctement un entier en C++, tu es si doué.

Reply

Marsh Posté le 11-08-2005 à 08:54:06    

Je te remercie pour ton aide Taz!
 
inet_pton c'est pas mal, j'ai réussi à m'en servir mais c'est bizarre, quand je lui passe l'adresse "192.168.1" en paramètre, il me retourne une valeur positive qui indique qu'il a bien réussi à convertir l'adresse...  :sarcastic:  
 
Enfin apparament, il y a juste à rajouter un test sur le nombre de '.' dans la chaine de caractères et c'est bon!  :)
 
EDIT : par contre, ca marche bien sous Cygwin, mais quand je l'ajoute dans mon application Gtk compilée sous Dev-Cpp ca marche beaucoup moins bien!!  :pfff:


Message édité par _p1c0_ le 11-08-2005 à 09:06:28
Reply

Marsh Posté le 11-08-2005 à 10:24:13    

Citation :

inet_pton c'est pas mal, j'ai réussi à m'en servir mais c'est bizarre, quand je lui passe l'adresse "192.168.1" en paramètre, il me retourne une valeur positive qui indique qu'il a bien réussi à convertir l'adresse...


 
[apres edit]oups j'ai rien dit ;)


Message édité par Rits75 le 11-08-2005 à 10:31:31
Reply

Marsh Posté le 11-08-2005 à 12:04:00    

Finalement j'ai abandonné inet_pton et je me suis concentré sur les flux... Et ca donne :
 

Code :
  1. bool fxdFwRegle::verifieIp(Glib::ustring adresse){
  2.      if( adresse == "" ) // aucune adresse => toutes les adresses
  3.          return true;
  4.    
  5.      std::string octet_tmp;
  6.      std::string tmp(adresse);
  7.      int octet, nb_pts = 0;
  8.      std::string::const_iterator it = tmp.begin();
  9.      // Vérification du nombre '.' dans la chaîne de caractères
  10.      while( (it != tmp.end()) && nb_pts < 4 ){
  11.             if( *it == '.' )
  12.                 nb_pts ++;
  13.             it ++;
  14.      }
  15.      if( nb_pts != 3){
  16.           // Le nombre de '.' est soit trop grand soit trop petit
  17.          return false;
  18.      }   
  19.    
  20.      if( tmp[tmp.size() -1] == '.' ){
  21.          // Le nombre de '.' est correct mais le dernier
  22.          // octet n'est pas renseigné
  23.          return false;
  24.      }
  25.    
  26.      // Vérification des octets
  27.      while( tmp != "" ){
  28.         // On récupère un octet
  29.         octet_tmp = tmp.substr(0,tmp.find_first_of("." ));
  30.         std::istringstream iss(octet_tmp);
  31.         if( ! (iss >> octet) ){
  32.             // Le flux ne contient pas d'entier => pas bon
  33.             return false;
  34.         }else{
  35.              if( !iss.eof() ){
  36.                  // Il y avait un entier mais il y avait aussi au moins
  37.                  // un mauvais caractère à la suite => pas bon  
  38.                  return false;
  39.              }else{
  40.                    if( octet < 0 || octet > 255 ){
  41.                        // c'est bien un entier mais trop grand ou négatif
  42.                        return false;     
  43.                    }
  44.              }
  45.         }
  46.         // On passe à l'octet suivant et si c'était le dernier, c'est fini
  47.         if( tmp.find_first_of("." ) != std::string::npos)
  48.             tmp = tmp.substr(tmp.find_first_of("." )+1);
  49.         else
  50.             tmp = "";
  51.      }
  52.      return true;
  53. }


 
Ca semble marcher mais si vous pouviez me donner vos commentaires, ce serait sympa!! J'ai pas cherché s'il existe une fonction qui compte le nombre de points dans la chaîne, enfin la boucle c'est suffisant. La vérification est surement assez rapide comme ca...
 
Merci d'avance!

Reply

Marsh Posté le 11-08-2005 à 12:34:32    

Code :
  1. bool checkIPv4Addr(const std::string &adresse){
  2.   char point;
  3.   unsigned int val;
  4.   std::istringstream iss(adresse);
  5.   for(size_t i=0; i<3; ++i) {
  6.     if((!(iss >> val)) || (val > 255))
  7.       return false;
  8.     if((!(iss >> point)) || (point != '.'))
  9.       return false;
  10.   }
  11.   return (iss >> val) && (val <= 255);
  12. }


 
tentative succinte parce que j'ai pas de temps pour faire ca et que ton gros pâté est moche ... C'est pas testé, pas même compilé, et rien n'est garanti sur la qualité de mon code :o (toute remarque est bienvenue à ce sujet, d'ailleurs [:petrus75])
 
Edit : corrections mineures dans le code
 
Edit 2 : corrections suite à la remarque ci-dessous :D (je ne suis plus trop sur de la précédence de ! vis à vis de ||, donc je paranthèse lourdement :o


Message édité par theshockwave le 11-08-2005 à 14:26:55
Reply

Marsh Posté le 11-08-2005 à 14:05:33    

Certes c'est plus beau  :D  mais ca marche pas... Tanpis je reste avec mon paté pas beau pour le moment!!  :)
 
EDIT : Finalement j'ai cherché vite fait le problème... C'est les négations qui sont mal placées... j'ai mis (!(iss >> val)) et c'est bon ca marche! Pareil pour (! (iss>>point) )
 
Merci beaucoup theShOcKwAvE!!  :bounce:


Message édité par _p1c0_ le 11-08-2005 à 14:11:28
Reply

Marsh Posté le 11-08-2005 à 15:20:03    

_p1c0_ a écrit :

Je te remercie pour ton aide Taz!
 
inet_pton c'est pas mal, j'ai réussi à m'en servir mais c'est bizarre, quand je lui passe l'adresse "192.168.1" en paramètre, il me retourne une valeur positive qui indique qu'il a bien réussi à convertir l'adresse...  :sarcastic:  


c'est faux

Reply

Marsh Posté le 11-08-2005 à 15:29:53    

Taz a écrit :

c'est faux


 
Ben alors peut être que j'ai fait une erreur dans mon test, j'ai effacé mon fichier vu que j'ai fait avec les flux... Enfin c'est bizarre quand même, je veux bien être mauvais mais là y a pas grand chose à mettre dans le code...  :??:

Reply

Marsh Posté le 11-08-2005 à 16:04:20    

_p1c0_ a écrit :

Ben alors peut être que j'ai fait une erreur dans mon test, j'ai effacé mon fichier vu que j'ai fait avec les flux... Enfin c'est bizarre quand même, je veux bien être mauvais mais là y a pas grand chose à mettre dans le code...  :??:


 
 
d'un autre côté, quand tu as ce genre de fonction à ta disposition ,tu peux te dire qu'elle fonctionne à merveille car elle a déjà probablement été utilisée par de nombreuses personnes avant toi. Donc pour un écart aussi grand vis-à-vis du comportement attendu, ca parait évident que l'erreur est dans ta façon de l'utiliser ou d'interpréter son retour :/

Reply

Marsh Posté le 11-08-2005 à 17:23:24    

theshockwave a écrit :

d'un autre côté, quand tu as ce genre de fonction à ta disposition ,tu peux te dire qu'elle fonctionne à merveille car elle a déjà probablement été utilisée par de nombreuses personnes avant toi. Donc pour un écart aussi grand vis-à-vis du comportement attendu, ca parait évident que l'erreur est dans ta façon de l'utiliser ou d'interpréter son retour :/


 
C'est vrai! Enfin j'ai pas cherché beaucoup non plus, je cherchais en même temps sur ca et sur les flux et j'ai fini par réussir à faire un truc qui marche avec les flux. En plus, ca compilait pas avec inet_pton et j'aurais passé beaucoup plus de temps à mon avis pour résoudre ce problème de compilation!!

Reply

Marsh Posté le 11-08-2005 à 17:35:09    

apparemment, la fonction inet_pton n'est pas dispo sous Visual Studio, si c'est ce compilateur que tu utilises ... (de même, je n'ai pas cherché, peut-être qu'il y a un équivalent, mais dans ce cas, il est sous un autre nom ou absent de la MSDN)

Reply

Marsh Posté le 11-08-2005 à 18:59:21    

theshockwave a écrit :

apparemment, la fonction inet_pton n'est pas dispo sous Visual Studio, si c'est ce compilateur que tu utilises ... (de même, je n'ai pas cherché, peut-être qu'il y a un équivalent, mais dans ce cas, il est sous un autre nom ou absent de la MSDN)


 
Non mais j'ai des problèmes parce que je compile sous Dev-Cpp mais j'utilise les fichiers d'entêtes de cygwin pour avoir inet_pton et du coup j'ai des redéfinitions..  :(  
 
Enfin c'est pas grave j'ai quelque chose qui marche c'est déjà ca!!  :)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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