more on strtok
This commit is contained in:
parent
42ead5b695
commit
c6fe2224bf
66
chap/C.tex
66
chap/C.tex
@ -479,9 +479,9 @@ avec les variables locales. Il est temps de passer à une gestion
|
|||||||
explicite de celle-ci~:
|
explicite de celle-ci~:
|
||||||
les fonctions \texttt{malloc} et \texttt{free} sont là pour ça.
|
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.
|
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~:
|
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
|
La page de man de getopt(3) contient des explications détaillées
|
||||||
et un exemple simple d'utilisation.
|
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 <string.h>
|
||||||
|
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}
|
\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}
|
\begin{itemize}
|
||||||
\item{Variables non initialisées.}
|
\item{Variables non initialisées.}
|
||||||
|
|
||||||
|
@ -5,8 +5,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
/*---------------------------------------------------------------------*/
|
/*-------------------------------------------------------*/
|
||||||
|
|
||||||
void dump_line(char *titre, char *ligne, int combien)
|
void dump_line(char *titre, char *ligne, int combien)
|
||||||
{
|
{
|
||||||
int foo;
|
int foo;
|
||||||
@ -23,8 +22,7 @@ for (foo=0; foo<combien; foo++) {
|
|||||||
}
|
}
|
||||||
puts("");
|
puts("");
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------*/
|
/*-------------------------------------------------------*/
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char input[] = "foo bar\tquux wiz";
|
char input[] = "foo bar\tquux wiz";
|
||||||
@ -54,4 +52,3 @@ printf(" index = %d\n", foo);
|
|||||||
printf(" and we have [%s]\n", input+foo);
|
printf(" and we have [%s]\n", input+foo);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------*/
|
|
||||||
|
Loading…
Reference in New Issue
Block a user