IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Caml Discussion :

[OCaml] Parser une ligne de commande


Sujet :

Caml

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6
    Points : 4
    Points
    4
    Par défaut [OCaml] Parser une ligne de commande
    Voila normalement un petit programme senser remplacer dans un fichier toutes les occurences d'un mot cle par un autre mot cle, cependant certains phenomene etranges surgissent et je ne vois pas le probleme :

    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
    81
    82
    83
     
     
    ########### Makefile for replace ##########
     
    OCAMLC	=	ocamlc
    CFLAGS	=	
    OBJS	=	replace.cmo main_replace.cmo
     
    .SUFFIXES:	.ml	.mli	.cmo	.cmi
     
    .ml.cmo:
    	$(OCAMLC)	-c	$<
     
    replace	:	${OBJS}
    	${OCAMLC}	${OBJS} -o $@
     
    clean	:
    	rm	-f	*.cm*	replace *~
     
     
    main_replace.ml
     
    open Sys;;
    open Array;;
    open Replace;;
     
    let main () =
      if not( file_exists (argv.(3))) then
     
        (
         print_endline("replace : " ^ argv.(3) ^ " : no such file");
         print_endline("usage : replace key1 key2 file")
        )
      else
        (
         if length (argv) <> 4 then
           print_endline("usage : replace key1 key2 file")  
         else
           (
             let source = open_in (argv.(3)) and target = open_out ("tmp") in
    	 try
    	  while true do
    	    let line = input_line source in
    	    let s = replace_line (argv.(1), argv.(2), line) in
    	    output_string target s
    	  done
    	with
    	| End_of_file -> 
    	    close_in source;
    	    close_out target;
                remove argv.(3);
                rename "tmp" argv.(3)
           )
        )
    ;;
     
    main ();;
     
    replace.ml
     
    open String;;  
     
      let replace_line keyword2replace keyword str =
        let i = ref 0 
        and res = ref "" 
        and lgt = length keyword 
        and lgt2 = length (str) 
        in
        while (!i <= (lgt2 - lgt)) do
          if ((sub str (!i + 1) lgt) = keyword2replace) then
    	(
    	 res := !res^keyword;
    	 i := !i + lgt
    	)
          else
    	(      
    	       res := !res ^ (make 1 str.[!i]); (*l'auto indentation est foireuse et je vois pas pourquoi*)
    	       i := !i + 1
    	      ) 
        done;
        res := !res^(sub str (!i+1) (lgt2 - !i));
        !res
    ;;
    Le mais ne fonctionne pas. (cf ci-dessous : mon deuxieme message)

    J'aurais vivement besoin d'aide, merci d'avance
    Oderint, dum metuant!!!

  2. #2
    Membre éclairé
    Avatar de GnuVince
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2004
    Messages
    679
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2004
    Messages : 679
    Points : 803
    Points
    803
    Par défaut
    Change les print_newline pour des print_endline.

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Le probleme est regler maintenant,, c'est vrai qu'avec des endline c'est mieux mais maintenant c'est le main qui est foireux, j'arrive pas a parser ma ligne de commande.

    Je sais que c'est avec Arg.parse mais j''ai du mal a comprendre son utilisation...
    Oderint, dum metuant!!!

  4. #4
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Je vais essayer de t'expliquer vite fait le fonctionnement de Arg.parse... car une fois que l'on a compris, c'est super simple !


    Deja, tu peux regarder le type de la fonction, ca renseigne deja un petit peu.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    # Arg.parse ;;
    - : (Arg.key * Arg.spec * Arg.doc) list -> Arg.anon_fun -> Arg.usage_msg -> unit
    Bon, a premier vu, ca fait un peu peur... mais en fait, c'est assez simple.

    la liste de sert a traiter ce que tu dois faire si tu a des options.
    le deuxieme argument est la fonction que tu dois appliquer une fois les options traite
    le denier argument est en fait le message qui va t'indiquer l'usage.

    Je vais maintenant te detailler un peu plus le triplet qui se trouve dans la liste. Il est compose de :

    • 1.la cle, qui correspond a l'option a traiter
      2.la fonction a effectuer pour traiter l'option
      3.d'un message qui va s'afficher quand tu vas appeler l'option help et qui decrit un peu le fonctionnement de l'option


    Voici par exemple de triplet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ("-t",
    Arg.Unit(fun () -> print_string "tu as utilise l'option -t" ),
    "message qui decris ce que fais l'option")
    et tu fais comme ca pour chaque option que tu dois traiter...

    Pour que tu vois un peu plus le fonctionnement, on va faire un petit programme tout simple qui te dire bonjour, et si tu specifie l'option -o, va te dire bonjour avec ton prenom.

    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
     
    (* je mais des petits flag pour me souvenir des options passe *)
    let flagNom =ref false (* ca me sert a me souvenir si l'option a ete passe *)
    let nom = ref "" (* la je vais stocker ton prenom *)
     
     
    (*maintenant, je vais passer faire la fonction qui affiche le bonjour *)
    let afficheNom () ->
       if !flagNom            (* je teste si l'option -o a ete passe *)
       then print_string ("bonjour " ^ !nom ^" !") 
       else print_string "bonjour l'inconnu"
     
    (* maintenant je vais faire la fonction qui parse *)
     
    let main () =
       Arg.parse [
          ("-o",Arg.String( fun tonNom -> begin 
                                             flagNom := true ;
                                             nom := tonNom
                                             end ),
            "affiche le nom de la personne dans le message bonjour" ) ]
         (afficheNom)
         "ce programme affiche le message bonjour"
     
     
    (* ensuite, il reste plus qu'a appeler la fonction main() *)
    let _ = main ()
    Bon, j'ai pas teste le programme, donc il est possible qu'il y ait des petites erreurs mais c'est le principe...

    si tu cherches la donc ocaml, va sur caml.inria.fr

    EDIT : Bon, je me suis rendu compte que mon exemple ne marchait pas... la fonction Arg.anon_fun doit etre de type string -> unit alors que moi, c'est unit -> unit .... mais bon, le principe est le meme.

  5. #5
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Bon, j'ai pas precise... mais si tu a plusieurs fois l'option qui est place, ca sera traite a chaque fois...

    Dans notre cas, si tu appeles ton programme avec deux fois l'option -o
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ myprog -o norbert -o helmut
    A chaque fois il va appeler la fonction qui traite cette option... mais pour nous, ca ne va prendre en compte que la dernier car on a pas fait gaffe si flagNom etait deja a true.

    si tu veux, tu peux modifier la fonction de traitement de la maniere suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    fun tonNom ->
         if !flagNom
         then nom := !nom ^ " et " ^ tonNom
         else ... (* comme avant *)
    et la tu auras bien la reponse
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ myprog -o norbert -o helmut
    bonjour norbert et helmut
    Bon, je te laisse adapter tout ca a ton programme.... ca va permettre de voir si tu as compris ou non...

Discussions similaires

  1. Parser une ligne de commande.
    Par shirohige dans le forum Générateurs de compilateur
    Réponses: 7
    Dernier message: 30/06/2013, 11h46
  2. Réponses: 11
    Dernier message: 20/12/2005, 16h29
  3. Parser une ligne saisie au clavier.
    Par Sylmandel dans le forum C++
    Réponses: 5
    Dernier message: 17/10/2005, 10h12
  4. lancer une mdb a partir d'une ligne de commande
    Par dpie dans le forum Access
    Réponses: 5
    Dernier message: 30/11/2004, 15h01
  5. [langage] Continuer a parser une ligne
    Par D[r]eadLock dans le forum Langage
    Réponses: 5
    Dernier message: 30/09/2002, 18h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo