Cartouche

Champ Valeur
Auteur·e Élise
Édition 2024-02-12
Taille des équipes 1 personne
Rendu via git, et dépôt $YEAR_pgc_c11, droits en lecture à delivery_collector
Compilation gcc -Wall -Wextra -Werror -I../libstu/include {sources de l'exercice} libstu.a

Barème

Critère Points
strlen token 2
strdup token 2
count token 2
sublen 4
split 6
REPL calculatrice 6
Total des critères 22
Note maximale 20

Règlement

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.

Instructions de rendu

Respectez à la lettre les noms de fichiers et leur emplacement dans le dépôt de rendu. S’il vous est demandé de rendre un fichier nommé hello.c sans qu’un nom de dossier soit précisé : rendez un fichier hello.c à la racine de votre dépôt.

La présence d’une étoile * signifie que le nom du fichier peut être n’importe lequel dès lors qu’il porte l’extension ou l’affixe (préfixe/suffixe) demandée. Elle signifie aussi qu’il est possible de rendre plusieurs fichiers.

La présence d’une double étoile ** signifie que les fichiers peuvent être placés n’importe où dans un dossier, y compris dans des sous-dossiers.

Pensez à faire des commits et des push fréquemment. Autrement nous ne pouvons pas vous aider à retrouver vos fichiers perdus.

Fonctions autorisées et interdites

Par défaut, toute fonction système (comme write) ou fonction des bibliothèques (comme printf ou puts) sont interdites.

À chaque exercice vous sera donné une liste de fonction autorisées, le cas échéant.

Tests unitaires

Vous devez rendre un fichier de test unitaire pour chaque fonction demandée.

Correction du code source en C

Chaque exercice sera compilé indépendamment avec les options -Wall -Wextra -Werror ainsi que votre libstu.

Introduction

L’objectif du jour, c’est de réussir à découper une chaîne de caractères en sous-chaînes. On va écrire des fonctions qui vont progressivement nous rapprocher de cet objectif.

Enfin, l’objectif sera d’appliquer l’utilisation de cette fonction à un REPL : il s’agit d’un programme qui lit des commandes et qui affiche leur résultat au fur et a mesure qu’il les reçoit et qu’il les exécute.

Exercice : strlen token

Fichiers à rendre : strlen_token.c, strlen_token.h, strlen_token.test.c Fonctions autorisées : aucune

Implémentez la fonction suivante :

unsigned int stu_strlen_token(const char *str, char token);

Elle se comporte comme strlen excepté le fait qu’elle s’arrête soit lorsqu’elle rencontre un \0, soit lorsqu’elle rencontre le caractère passé en argument.

Exemple :

  • si vous lui passez hello;world et le symbole ;, elle renverra 5 ;
  • si vous lui passez hello world et le symbole ;, elle renverra 11.

Exercice : strdup token

Fichiers à rendre : strdup_token.c, strdup_token.h, strdup_tokentest.c Fonctions autorisées : maloc

Sur le même principe que stu_strlen_token, implémentez stu_strdup_token.

Exercice : count token

Fichiers à rendre : count_token.c, count_token.h, count_token.test.c Fonctions autorisées : aucune

Implémentez la fonction suivante :

unsigned int count_token(const char *str, char token);

Elle renvoie le nombre d’occurrences du caractère token dans la chaîne str.

Exercice : sublen

Fichiers à rendre : sublen.c, sublen.h, sublen.test.c Fonctions autorisées : malloc

Implémentez la fonction suivante :

unsigned int *sublen(const char *str, char token);

Elle renvoie un tableau d’entier non signés qui valent la taille de toutes les sous chaînes séparées par token.

Exemple :

  • si vous lui passez abc;def;ghi et le token ; elle renverra un tableau avec les valeurs :
    • 3
    • 3
    • 3
  • si vous lui passez abc;;def;ghi et le token ; elle renverra un tableau avec les valeurs :
    • 3
    • 0
    • 3
    • 3
  • si vous lui passez abc;def;ghi; et le token ; elle renverra un tableau avec les valeurs :
    • 3
    • 3
    • 3
    • 0
  • si vous lui passez hello;world;this;is;me et le token ; elle renverra un tableau avec les valeurs :
    • 5
    • 5
    • 4
    • 2
    • 2

Exercice : split

Fichiers à rendre : split.c, split.h, split.test.c Fonctions autorisées : malloc

Implémentez la fonction suivante :

char **split(const char *str, char token);

Elle doit découper une chaîne de caractère en sous chaîne. Les sous chaînes sont délimitées par token. token ne doit pas être présent dans les sous-chaînes renvoyées.

Le dernier pointeur du tableau renvoyé doit être à NULL.

Vous devez allouer chaque sous-chaîne ainsi que le tableau qui les stockera toutes. Les sous-chaînes étant de type char *, le tableau qui les stocke est de type char **.

Exemples de test :

Test(split, normal_1) {
	char **res;

	res = split("abc;def;ghi", ';');
	cr_assert(eq(str, res[0], "abc"));
	cr_assert(eq(str, res[1], "def"));
	cr_assert(eq(str, res[2], "ghi"));
	cr_assert(eq(ptr, res[3], NULL));
}

Test(split, trailing_1) {
	char **res;

	res = split("abc;def;ghi;", ';');
	cr_assert(eq(str, res[0], "abc"));
	cr_assert(eq(str, res[1], "def"));
	cr_assert(eq(str, res[2], "ghi"));
	cr_assert(eq(str, res[3], ""));
	cr_assert(eq(ptr, res[4], NULL));
}

Théorie : get_next_line

Pour vous aider dans vos projets, vous serez de temps en temps autorisés à utiliser la fonction suivante : get_next_line.

Cette fonction lit sur le descripteur de fichier que vous lui donnez et vous renvoie une ligne dès qu’elle est disponible (sans le \n) final. La chaîne de caractère renvoyée est crée avec malloc et c’est votre responsabilité de la free.

Si elle s’aperçoit que le fichier est terminé, elle renvoi NULL. Elle ne renvoie jamais de ligne incomplète.

Lorsque vous en avez fini avec get_next_line, vous pouvez lui demander de libérer la mémoire qu’il retient en l’appellant avec 1-1.

#include <stdlib.h>
#include <stdio.h>
#include <tc/gnl.h>

int main(void)
{
    char *line;
    int i;

    line = get_next_line(0);
    i = 1;
    while (line) {
        printf("%d: %s\n", i++, line);
        free(line);
        line = get_next_line(0);
    }
    // reset gnl carry (free its internal memory)
    get_next_line(-1);
}

Compilez avec -lgnl.

Exercice : REPL calculatrice

Fichiers à rendre : repl/**/*.c, repl/**/*.h Fonctions autorisées : malloc, free, get_next_line, read, write.

Écrivez un programme qui lit des commandes sur l’entrée standard.

Commandes :

  • push [nb_1] [nb_2] ... [nb_n] permet de stocker de nouveaux nombres
  • pop [idx_1] [idx_2] ... [idx_n] supprime les nombres aux positions données
  • print affiche tous les nombres stockés
  • sum fait la somme de tous les nombres stockés et l’affiche
  • avg fait la moyenne de tous les nombres stockés et l’affiche
  • exit quitte proprement le programme