Split d'une string

Le
Guillaume GOURDIN
Bonjour à tous,

comment ecririez-vous une fonction permettant de séparer les arguments
d'une ligne de commande. Autrement dit une fonction dont le prototype serait

bool split_args(const string & command_line, vector<string> & args)

et qui remplirait le vector 'args', en prenant soin:
- de gérer correctement les espaces mutiples
- de gérer correctement les guillemets

Merci pour votre aide.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Mickaël Wolff
Le #18054911
Guillaume GOURDIN a écrit :
Bonjour à tous,

comment ecririez-vous une fonction permettant de séparer les arguments
d'une ligne de commande. Autrement dit une fonction dont le prototype
serait



Je ne l'écrirais pas :

;)

bool split_args(const string & command_line, vector<string> & args)

et qui remplirait le vector 'args', en prenant soin:
- de gérer correctement les espaces mutiples
- de gérer correctement les guillemets



Pourquoi un vector ? Tu ne veux pas plutôt parler d'une map<string,
string> (pour avoir les arguments en clés) ?

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
James Kanze
Le #18054901
On Dec 5, 2:50 pm, Guillaume GOURDIN
comment ecririez-vous une fonction permettant de séparer les
arguments d'une ligne de commande. Autrement dit une fonction
dont le prototype serait



bool split_args(const string & command_line, vector<string> & args)



et qui remplirait le vector 'args', en prenant soin:
- de gérer correctement les espaces mutiples
- de gérer correctement les guillemets



Comme tu écrirais une fonction pour parser n'importe quoi. Le
code dans mon ParsableString (dans le sous-système Text à mon
site) pourrait en donner quelques ideas, mais il risque d'une
côté d'en faire trop (tous les séquences d'escape), de l'autre
pas assez (pas de gobbing). En gros, je crois qu'avec un petit
automat, on en sortirait assez bien. (Encore que... dans la
construction d'un mot, il faut bien noter quelles parties ont
été quotées, et comment; quelque chose comme *.'cc' fait
l'expansion de l'étoile, quelque chose comme '*.'cc non.

Et évidemment, pour faire l'expansion, il faut pouvoir lire les
répertoires et exécuter des commandes en récupérant leurs
sorties standard ; deux choses qui exige du code qui dépend du
système.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Guillaume GOURDIN
Le #18055271
> Pourquoi un vector ? Tu ne veux pas plutôt parler d'une map<string,
string> (pour avoir les arguments en clés) ?



Je ne comprends pas: le but est d'appeler un exec, il faut donc juste
séparer les arguments, me trompé-je? Par exemple: "ls 'a b c' d e" me
rendrait 4 arguments:
"ls"
"a b c"
"d"
"e"

Merci.
James Kanze
Le #18056431
On Dec 5, 3:05 pm, Mickaël Wolff
Guillaume GOURDIN a écrit :



> comment ecririez-vous une fonction permettant de séparer les
> arguments d'une ligne de commande. Autrement dit une
> fonction dont le prototype serait



Je ne l'écrirais pas :



;)



Je n'ai pas l'impression que ça fait ce qu'il veut. (En général,
j'ai l'impression que ce qu'il fait est quelque chose que
prèsque personne ne veut.)

> bool split_args(const string & command_line, vector<string> & args)



> et qui remplirait le vector 'args', en prenant soin:
> - de gérer correctement les espaces mutiples
> - de gérer correctement les guillemets



Pourquoi un vector ? Tu ne veux pas plutôt parler d'une
map<string, string> (pour avoir les arguments en clés) ?



D'où doivent venir les clés ? C'est en premier lieu une liste
des paramètres qu'il cherche à avoir. (Dans la tradition Unix,
ça serait des noms de fichiers.)

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Mickaël Wolff
Le #18056421
Guillaume GOURDIN a écrit :
Je ne comprends pas: le but est d'appeler un exec, il faut donc juste
séparer les arguments, me trompé-je? Par exemple: "ls 'a b c' d e" me
rendrait 4 arguments:
"ls"
"a b c"
"d"
"e"



Ah oui, si effectivement tu veux quelque chose d'aussi simple, un
vector suffira. Cependant, dans le monde unix, lorsqu'on parle
d'arguments de la ligne de commande, on pense fatalement au
commutateurs, et donc à associer une valeur à une option.

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Fabien LE LEZ
Le #18056411
On Fri, 05 Dec 2008 15:05:00 +0100, Mickaël Wolff

Pourquoi un vector ? Tu ne veux pas plutôt parler d'une map<string,
string> (pour avoir les arguments en clés) ?



Ça, ça vient après : c'est le décodage des arguments.

Je vois mal une bibliothèque générique savoir quels arguments sont des
options pour un truc comme, par exemple, tar :

tar cf archive.tar bidule truc

("cf", malgré l'absence de "-", est un groupe d'options, et
"archive.tar" est le nom de l'archive à créer à cause du "f". "bidul"
et "truc" sont les fichiers à mettre dans l'archive.)
James Kanze
Le #18060751
On Dec 5, 5:52 pm, Mickaël Wolff
Guillaume GOURDIN a écrit :



> Je ne comprends pas: le but est d'appeler un exec, il faut
> donc juste séparer les arguments, me trompé-je? Par exemple:
> "ls 'a b c' d e" me rendrait 4 arguments:
> "ls"
> "a b c"
> "d"
> "e"



Ah oui, si effectivement tu veux quelque chose d'aussi simple,
un vector suffira. Cependant, dans le monde unix, lorsqu'on
parle d'arguments de la ligne de commande, on pense fatalement
au commutateurs, et donc à associer une valeur à une option.



Tiens, c'est la première fois que je vois le mot « switch »
traduit par « commutateur ». Dans les cercles que je fréquente,
on dit « option », quand ce n'est pas carrément « switch  ».

Et évidemment, dans le monde Unix, ce que démandait Guillaume
est bien fait par le shell, quand on invoque le programme par un
shell (et la norme Posix exige que la chaîne donnée à la
fonction system passe par un shell). Mais la question était
clairment posée : comment faire ce que fait le shell (et il y a
des occasions où on aimerait le faire sous Unix, aussi).

Aussi dans le monde Unix, lorsqu'on parle d'arguments de la
ligne de commande, on pense en premier lieu à une liste
(éventuellement vide) de noms de fichiers. Les options viennent
en plus, et s'associent en général chacune à une variable. À cet
égard, j'ai deux solutions sur ma site, CommandLine, associé
avec Option et les classes qui en dérivent, pour la gestion des
options, et MultifileInputStream, pour la liste des fichiers.
Pour une fois, je crois que j'ai cerné le problème nettement
mieux que Boost. À titre d'exemple :

À la portée d'un namespace :
Gabi::BooleenOption b( 'b' ) ;
Gabi::NumericOption n( 'n' ) ;

Et dans main :
int
main( int argc, char** argv )
{
Gabi::CommandLine::instance().parse( argc, argv ) ;
Gabi::MultifileInputStream input(
Gabi::CommandLine::instance().begin(),
Gabi::CommandLine::instance().end(),
new Gabi::CannotOpen ) ;
// ...
return Gabi::ProgramStatus::instance().returnCode() ;
}

Les variables b et n se convertit en bool et en int
implicitement, et les options qui leur correspondent ne se
trouvent pas dans la séquence définie par les itérateurs de
CommandLine.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
James Kanze
Le #18060891
On Dec 5, 5:56 pm, Fabien LE LEZ
On Fri, 05 Dec 2008 15:05:00 +0100, Mickaël Wolff



>Pourquoi un vector ? Tu ne veux pas plutôt parler d'une
>map<string, string> (pour avoir les arguments en clés) ?



Ça, ça vient après : c'est le décodage des arguments.



Je vois mal une bibliothèque générique savoir quels arguments
sont des options pour un truc comme, par exemple, tar :



tar cf archive.tar bidule truc



("cf", malgré l'absence de "-", est un groupe d'options, et
"archive.tar" est le nom de l'archive à créer à cause du "f".
"bidul" et "truc" sont les fichiers à mettre dans l'archive.)



C'est une question de langage:-). Le "cf" n'est pas un groupe
d'options, mais plutôt une commande. Sauf qu'évidemment, on peut
l'écrire "-cf" aussi, sans qu'il cesse d'être une commande pour
autant. (Ça, au moins, avec la version de GNU. L'interface de
tar n'est pas spécifiée par Posix/Open Group, et en fait varie
beaucoup d'une Unix à un autre. Historiquement, je crois que le
'-' était obligatoire.)

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Fabien LE LEZ
Le #18060991
On Sat, 6 Dec 2008 01:58:34 -0800 (PST), James Kanze

C'est une question de langage:-). Le "cf" n'est pas un groupe
d'options, mais plutôt une commande. Sauf qu'évidemment, on peut
l'écrire "-cf" aussi, sans qu'il cesse d'être une commande pour
autant.



En fait, l'écriture "normale", c'est :
tar c -f archive.tar bidule truc

Remplacer "c -f" par "cf" est un raccourci, bien pratique mais qui ne
facilite pas la lecture...

(Ça, au moins, avec la version de GNU. L'interface de
tar n'est pas spécifiée par Posix/Open Group, et en fait varie
beaucoup d'une Unix à un autre. Historiquement, je crois que le
'-' était obligatoire.)



Sous Linux (seul système Posix que je connais), l'écriture la plus
cohérente avec les autres options serait
tar -cf ...
ou
tar -c -f ...

Mébon, manisfestement, la cohérence n'est pas toujours là... Y'a qu'à
voir la syntaxe de dd...
Wykaaa
Le #18062711
Guillaume GOURDIN a écrit :
Bonjour à tous,

comment ecririez-vous une fonction permettant de séparer les arguments
d'une ligne de commande. Autrement dit une fonction dont le prototype
serait

bool split_args(const string & command_line, vector<string> & args)

et qui remplirait le vector 'args', en prenant soin:
- de gérer correctement les espaces mutiples
- de gérer correctement les guillemets

Merci pour votre aide.


Ca relève de l'analyse lexicale et/ou syntaxique, donc voir les outils
lex, flex et/ou yacc et bison.

Pourquoi réinventer la poudre ?
Publicité
Poster une réponse
Anonyme