Champ Valeur
Auteur·e Élise
Édition 2023-12-01
Durée 1,5 semaine
Taille des équipes 1 personne
Rendu via git, dépôt $YEAR_cat, droits en lecture à delivery_collector

Barème

Critères Points
Lecture en boucle depuis l’entrée standard 4
Lecture en boucle depuis un fichier 4
Plusieurs fichiers et/ou - en argument 4
Helper 4
Vraies erreurs 4
Caractères invisible 4
Points accessibles 24
Malus par ligne contenant une faute de norme -0,5
Malus dépôt sale -5
Note maximale 20

Règlement de projet

La réalisation de cet exercice est assujettie aux règles en vigueur dans l’école en matière de triche et de normalisation. Tricher vous expose à de graves sanctions.

Vous devez respecter les règles de normalisation suivantes : https://git.ecole-89.com/eriizu/coding_style/src/branch/main/norm.md

Le non-respect de la norme vous fera perdre une partie ou la totalité des points qui auraient pu être acquis, sur l’ensemble du rendu.

Fichiers à rendre

La structure de votre dépôt doit être la suivante :

  • fichiers *.c dans src/
  • fichiers *.h dans include/

Comme vous devez rendre un programme, vous devez rendre une fonction main. Son fichier, devra s’appeler main.c, être dans le dossier src/ et respecter les règles de normalisation (il ne s’agit pas d’un fichier de test.)

Votre projet sera compilé avec la commande suivante :

gcc -Wall -Wextra -Werror -Iinclude ./src/*.c -o stu_cat

Fonctions autorisées et interdites

Pour tout le sujet, les fonctions autorisées sont :

  • open
  • close
  • write
  • read
  • malloc
  • free

Tests

Vous pouvez inclure des main de test dans votre rendu. Ces main doivent être rendus dans un répertoire test/. Vous pouvez organiser ce répertoire comme vous le souhaitez.

Fonctionnalités de base

Vous devez implémenter un clone partiel de la commande cat. Il s’agit d’un programme qui est capable de lire sur plusieurs entrées différentes et de restituer ce qui a été lu sur la sortie standard.

cat a plusieurs modes de fonctionnement :

  • lecture sur l’entrée standard ;
  • lecture sur un fichier passé en argument ; et
  • lecture mixte sur fichier et sur entrée standard avec -.

cat peut lire des fichiers de n’importe quelle taille.

EOF

Dans tous les cas, la lecture sur un fichier ou sur l’entrée standard cesse dès lors qu’il n’y a plus rien à lire. Lorsqu’il n’y a plus rien à lire on dit que l’on est à EOF (end of file – fin de fichier). On sait que l’on est à EOF lorsque read nous renvoie 0.

Quoi qu’il l’arrive, pour chacune des fonctionnalités demandées, vous devez vous comporter comme cat.

Arguments

Lorsque cat ne reçois aucun argument, il lit sur l’entrée standard.

Lorsque cat reçoit 1 ou plusieurs arguments, il va essayer d’ouvrir les fichiers dont le nom est donné en argument et les lire, les uns après les autres, en affichant leur contenu sur la sortie standard.

Attention : s’il y a un argument qui contient un tiret seul, au lieu d’ouvrir un fichier qui porterait ce nom, cat lit sur l’entrée standard.

Erreurs

Lorsqu’un fichier ne peut pas être ouvert, vous devez afficher une erreur et continuer a traiter les arguments qui suivent.

Vos erreurs doivent être formatées ainsi : ARGV0: FILE_NAME: Cannot process file.

Remplacez :

  • ARGV0 : par l’argument 0 de votre programme ;
  • FILE_NAME : par le nom du fichier que vous n’arrivez pas à ouvrir ou à lire.

Si cat n’a pas réussi à lire un fichier, son code de sortie sera 1 au lieu de 0.

Exemples de comportement

Restitution de l’entrée standard

Le caractère < ne fait pas partie de l’entrée et de la sortie standard, il a été rajouté à l’exemple pour différencier les lignes qui ont été écrites au clavier de la réponse du programme exécuté :

  • < écriture au clavier ;
  • ^D signifie que l’on a appuyé sur ctrl+d, il ne va pas s’afficher non plus.
[sh] $ ./stu_cat
< hello
hello
< tata
tata
< toto
toto
^D
[sh] $ ./stu_cat << EOF
< hello
< world
< this
< is
< me
< life should be
< fun for everyone
< EOF
hello
world
this
is
me
life should be
fun for everyone
[sh] $

Restitution de gros fichiers

[sh] $ man malloc > manmalloc
[sh] $ man gcc > mangcc 2> /dev/null
[sh] $ wc manmalloc
  205  1284 11167 manmalloc
[sh] $ wc mangcc
  18805  163494 1305222 mangcc
[sh] $ ./stu_cat manmalloc mangcc | wc
  19010  164778 1316389

Restitution d’un fichier et de l’entrée standard

[sh] $ echo "patate" | ./stu_cat
patate
[sh] $ echo "patate" | ./stu_cat src/main.c -
int main(int ac, char **av)
{
	[...]
}
patate
[sh] $ echo "patate" | ./stu_cat - src/main.c
patate
int main(int ac, char **av)
{
	[...]
}

Par où commencer ?

Étapes

Si vous ne savez pas par quoi commencer, faites les choses dans cet ordre.

  1. Écrivez une fonction qui lit une fois sur l’entrée standard et affiche immédiatement ce qu’elle a lu,
  2. Écrivez une fonction qui fait la même chose, mais dans une boucle,
    • ne mettez pas malloc et free dans la boucle,
    • vous n’avez pas besoin de ré-allouer à chaque tour de boucle.
  3. Au lieu de lire sur l’entrée standard, faite prendre à la fonction le descripteur de fichier en paramètre.
  4. Récupérez le nom d’un fichier depuis les arguments de votre programme,
    • utilisez open dessus,
    • passez le descripteur de fichier à votre fonction qui lit et écrit en boucle.
  5. Si le nom du fichier que vous avez reçu est un -,
    • au lieu d’ouvrir un fichier, lisez sur votre entrée standard.
  6. Enfin, au lieu de faire ça pour un seul argument, faites le pour tous les arguments reçus.

Re-découpage et prise de notes

Je vous conseille de découper ces étapes en sous-étapes et de suivre votre progression avec un outil de votre choix comme :

  • un outil de prise de note :
    • Obsidian,
    • Notion,
    • OneNote,
    • ce que vous voulez ;
  • un tableau kanban :
    • du genre Trello,
    • l’onglet Projet de votre dépôt sur la forge logicielle,
    • ou ce qu’intègre votre outil de prise de note (plugin Kanban sur Obsidian, modèle Kanban sur notion, etc.) ;
  • un carnet.

Fonctionnalité : helper

Lorsqu’on lance cat avec l’option --help, un message d’aide s’affiche pour savoir qu’elles options on peut utiliser.

Implémentez quelque chose de similaire mais qui se déclenche lorsqu’il y a le drapeau -h.

Reproduisez le message d’aide de cat pour les fonctionnalités que vous avec implémenté (et pas une plus)

Fonctionnalité : vraies erreurs

Fonction autorisée supplémentaire : strerror

Au lieu d’afficher le même message d’erreur dans toutes les situations, utilisez strerror pour récupérer une description de l’erreur qu’il s’est produite et pour l’afficher.

Fonctionnalité : caractères invisibles

Pasted image 20231204125413.png

Implémentez les options -E et -T.

Le comportement attendu est celui-ci :

[sh] $ echo -e "\ttototata"
        tototata
[sh] $ echo -e "\ttototata" | ./stu_cat -TE
^Itototata$
[sh] $ echo -e "\ttototata" | ./stu_cat -E
	tototata$
[sh] $ echo -e "\ttototata" | ./stu_cat -T
^Itototata
[sh] $