diff --git a/chap/C.tex b/chap/C.tex index 958b86e..3d74e83 100644 --- a/chap/C.tex +++ b/chap/C.tex @@ -479,9 +479,9 @@ avec les variables locales. Il est temps de passer à une gestion explicite de celle-ci~: les fonctions \texttt{malloc} et \texttt{free} sont là pour ça. -La première demande au mc/p de nous préter une certaine quantité +La première fonction demande au mc/p de nous préter une certaine quantité de mémoire, que nous pourront utiliser à notre guise. -Et la seconde restitue la zone mémoire au système sous-jacent. +Et la seconde restitue cette zone mémoire au système sous-jacent. Un rapide synopsis minimal d'utilisation~: @@ -536,10 +536,72 @@ extern int optind, opterr, optopt; La page de man de getopt(3) contient des explications détaillées et un exemple simple d'utilisation. +% ========================================================= +% Sun Sep 3 05:48:37 UTC 2023 +% +% +\section{Analyser une ligne de texte} \index{parser} + +Nous désirons implémenter une interface en ligne de commande +(aka CLI\index{CLI}) pour un enchainement simple d'intructions +assez semblables. On peut aussi voir ça comme la création +d'un \textsl{domain specific language} (aka DSL\index{DSL}). + +Pour être cohérent avec le shell, nous allons utiliser la +même méthode de séparation des mots sur la ligne à +décomposer~: +utiliser une liste pré-définie de séparateur de champs, +comme le \$IFS du shell. + +\subsection{la fonction \texttt{strtok}} \index{strtok} + +Cette fonction nous permet de « découper » notre ligne de commande +en \textsl{tokens} par un ensemble de +caractères de séparation appelé \texttt{delim} dans cet extrait +du man\index{man}. + + +\begin{verbatim} + #include + char *strtok(char *str, const char *delim); + + The strtok() function breaks a string into a sequence of zero or more + nonempty tokens. On the first call to strtok(), the string to be + parsed should be specified in str. In each subsequent call that should + parse the same string, str must be NULL. +\end{verbatim} + +Concrètement, nous allons utiliser deux séparateurs très classiques, +l'espace et la tabulation \texttt{ delim = "\symbol{92}t ";}. +on peut ensuite aller regarder dans la mémoire ce qui s'y passe~: + +\begin{verbatim} + --- chaine d'origine +66 6f 6f 20 20 20 62 61 72 09 71 75 75 78 20 77 69 7a 00 + f o o b a r q u u x w i z + --- 1er strtok +66 6f 6f 00 20 20 62 61 72 09 71 75 75 78 20 77 69 7a 00 + f o o b a r q u u x w i z + got [foo] +\end{verbatim} + +Déja on peut constater que la chaine de départ est modifiée, ce qui +risque de causer des soucis, mais on en parlera plus tard. + + + + +\subsection{Le programme complet} + +\lstinputlisting[language=c]{code/C/demo-strtok.c} + % ========================================================= \section{Erreurs classiques} +Le C est un langage parsemé de fosses, de chausse-trapes et de +pièges fourbes et sournois. Sans parler des UBs, hein\dots + \begin{itemize} \item{Variables non initialisées.} diff --git a/code/C/demo-strtok.c b/code/C/demo-strtok.c index 7dad911..ac75a4b 100644 --- a/code/C/demo-strtok.c +++ b/code/C/demo-strtok.c @@ -5,8 +5,7 @@ #include #include #include -/*---------------------------------------------------------------------*/ - +/*-------------------------------------------------------*/ void dump_line(char *titre, char *ligne, int combien) { int foo; @@ -23,8 +22,7 @@ for (foo=0; foo