Skip to content

Classe inversée : Interactions Utilisateur & Système

scanf & args

1. Cours

Maintenant que vous connaissez les pointeurs et les chaînes, nous allons voir comment faire interagir votre programme avec le monde extérieur : l'utilisateur (via le clavier) et le système (via la ligne de commande).

1. scanf : Pourquoi faut-il des & partout ?

Vous avez sans doute appris par cœur qu'il faut mettre un & dans un scanf, comme ceci : scanf("%d", &age);. Grâce au cours précédent sur les pointeurs, vous pouvez enfin comprendre pourquoi.

  • Le problème : scanf est une fonction qui doit modifier la variable age pour y mettre ce que l'utilisateur tape.
  • La règle (vue au TP précédent) : Pour qu'une fonction modifie une variable, elle a besoin de son ADRESSE.

C'est pour cela qu'on envoie &age (l'adresse) et non age (la valeur). scanf est le facteur, &age est l'adresse de livraison.

L'exception qui confirme la règle : Les chaînes Regardez ce code :

char nom[50];
scanf("%s", nom); // PAS DE & ICI !

  • Pourquoi ? Parce que nom est un tableau. En C, le nom d'un tableau est déjà l'adresse de sa première case. Ajouter un & serait redondant (et techniquement faux).

2. Les arguments du main : Parler au programme au lancement

Jusqu'ici, votre main ressemblait à int main(). Mais un programme professionnel doit pouvoir recevoir des options dès son lancement, comme la commande ls -l ou gcc main.c.

Pour cela, on change la signature du main :

int main(int argc, char *argv[])

Voici ce que ces deux variables contiennent :

A. argc (ARGument Count)

C'est un entier qui indique combien de mots ont été tapés dans la ligne de commande.

  • Attention : Le nom du programme compte pour 1 !

B. argv (ARGument Vector)

C'est un tableau de chaînes de caractères (char *argv[]). Chaque case contient un des mots tapés.

Exemple concret : Imaginez que vous lanciez votre programme dans le terminal ainsi : ./mon_programme start --verbose

Voici ce que reçoit le main :

Variable Valeur Explication
argc 3 Il y a 3 mots en tout.
argv[0] "./mon_programme" Le nom du programme (toujours en premier).
argv[1] "start" Le premier argument réel.
argv[2] "--verbose" Le deuxième argument.
argv[3] NULL Marque la fin du tableau (par sécurité).

2. Exercices Pratiques

Exercice 1 : Le Formulaire (scanf sécurisé)

Écrivez un programme qui demande :

  1. L'âge de l'utilisateur (entier).
  2. Sa taille en mètres (float ou double).
  3. Son prénom (chaîne sans espaces).

Affichez ensuite un résumé : "Bonjour [Prénom], vous avez [Age] ans et mesurez [Taille]m."

  • Défi : Faites attention à où vous mettez les & et où vous ne les mettez pas !

Exercice 2 : L'Écho (Découverte de argv)

Écrivez un programme qui affiche simplement tous les arguments qu'on lui passe, un par ligne, avec leur numéro d'index.

Exemple d'exécution : ./exo2 salut tout le monde

Sortie attendue :

Argument 0 : ./exo2
Argument 1 : salut
Argument 2 : tout
Argument 3 : le
Argument 4 : monde

Indice : Utilisez une boucle for qui va de 0 à argc.

Exercice 3 : La Calculatrice en Ligne de Commande

Nous voulons créer un programme qui calcule directement depuis le terminal. Usage attendu : ./calc 10 + 5 ou ./calc 8 x 2

Outils nécessaires :

  • argv[1] sera le premier nombre (sous forme de chaîne !).
  • argv[2] sera l'opérateur ("+", "x", etc.).
  • argv[3] sera le deuxième nombre.
  • Problème : argv contient du texte (char*). On ne peut pas faire "10" + "5".
  • Solution : La fonction sscanf qui fait la même chose que scanf, mais depuis une chaine de caractères au lieu de le faire depuis l'entrée standard.
    • Exemple :
       int n;
       char * s = "42";   
       sscanf(s,"%d",&n); // n vaut 42
      

Consignes :

  1. Vérifiez d'abord si argc vaut bien 4. Sinon, affichez une erreur "Usage: ./calc " et quittez.
  2. Convertissez les arguments 1 et 3 en entiers avec sscanf.
  3. Utilisez strcmp ou comparez le premier caractère argv[2][0] pour savoir quelle opération faire.
  4. Affichez le résultat.

Exercice 4 (Avancé) : Le Login sécurisé

Créez un programme qui simule un accès sécurisé. Usage : ./login utilisateur motdepasse

  1. Le programme attend un nom d'utilisateur spécifique (ex: "admin") et un code (ex: "1234").
  2. Si les arguments correspondent, affichez "Accès autorisé".
  3. Si le mot de passe est faux, affichez "Accès refusé".
  4. Important : Si l'utilisateur oublie de mettre les arguments (ex: il tape juste ./login), le programme ne doit pas planter (Segmentation Fault). Il doit afficher un message d'aide.

Sujet rédigé à l'aide de ChatGPT et Gemini