Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Split d'une string

14 réponses
Avatar
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.

10 réponses

1 2
Avatar
Mickaël Wolff
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 :
<http://www.boost.org/doc/libs/1_37_0/doc/html/program_options.html>

;)

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
Avatar
James Kanze
On Dec 5, 2:50 pm, Guillaume GOURDIN wrote:
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
Avatar
Guillaume GOURDIN
> 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.
Avatar
James Kanze
On Dec 5, 3:05 pm, Mickaël Wolff wrote:
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 :
<http://www.boost.org/doc/libs/1_37_0/doc/html/program_options.html>



;)



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
Avatar
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.

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
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.)
Avatar
James Kanze
On Dec 5, 5:52 pm, Mickaël Wolff wrote:
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
Avatar
James Kanze
On Dec 5, 5:56 pm, Fabien LE LEZ wrote:
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
Avatar
Fabien LE LEZ
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...
Avatar
Wykaaa
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 ?
1 2