17/09/2018
4H
Pré-requis
Usage gcc ,lib stdlib et stdio , les entiers , char
gcc / gdb C ansi
utilisation du poste de travail linux local
But
Manipuler les caractères avec le C avec la fonction printf.
Utiliser , argc et argv
utilisation de gdb pour comprendre les codes en pas a pas
Dans un répertoire tp1 (dans votre Works)
faire une répertoire char dans lequel vous ferez l'exercice.
Vous placerez un répertoire par exercice.
compte rendu avant la fin du tp1 (pdf) sur 'classe'@workboot.fr avec son tar du tp1
bien utiliser gdb
Pour ce tp utiliser
man ascii
Dans un repertoire char, char.c
/********************************/
/* Code le char */
/* (c)2021 18/10 Bogt */
/********************************/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char caractere;
caractere = 0x41;
printf( "Le caractère est %c \n",caractere);
/* que se passe t'il avec ce caractère */
return EXIT_SUCCESS;
}
Dans un répertoire char2 , faire une copie du précédent en char2.c
et modifier avec 0x42 au lieu de 0x41 comme valeur dans le caractère, que constatez vous.
%c sert a quoi pour le printf?
pour vous aider man ascii
dans un répertoire minmaj , minmaj.c
Que donne le caractère 0x41 et 0x61
0x42 et 0x62
combien faut il ajouter pour passer de Majuscule en minuscule? en décimal et en hexadécimal .
dans un répertoire string , string.c
/********************************/
/* Code chaine de char */
/* (c)2021 18/10 Bogt */
/********************************/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char chaine[100]="Bonjour le monde";
printf( "La chaine est %s \n",chaine);
/* que se passe t'il ici?*/
return EXIT_SUCCESS;
}
Nous avons une chaîne de caractère contenant les codes ascii de Bonjour le monde !
man ascii (si besoin)
répertoire chaine0 le code chaine0.c
/********************************/
/* Code manipulation de chaine */
/* (c)2021 18/10 Bogt */
/********************************/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char chaine[100]="Bonjour le monde";
chaine[0]='A';
chaine[1]=0x41;
printf( "Le caractère est %s \n",chaine);
/* que se passe t'il ici?*/
return EXIT_SUCCESS;
}
expliquer la présence du 1er A et du 2ème A ?
dans un répertoire chaine1, chaine1.c
/********************************/
/* Code le caractere /0 */
/* (c)2021 18/10 Bogt */
/********************************/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char chaine[100]="Bonjour le monde";
chaine[7]=0; /* chaine[7]='\0' */
printf( "Le caractère est %s \n",chaine);
/* que se passe t'il ici?*/
return EXIT_SUCCESS;
}
Avez vous vu que nous avons fait disparaître le monde !! ?
donc
A quoi sert le caractère NULL dans une chaîne ?
indice , arg est la contraction de argument
c pour counter (compteur)
v pour value (valeur)
dans un répertoire param, param.c
Écrire un code qui vous affichera la valeur de argc de votre programme.
tester avec
./param deux
puis
./param deux trois
puis
./param deux trois quatre
mince a quoi sert argc ?
Déjà vu au tp0 !
pour c comme counter ?
répertoire param2, param2.c
Écrire un programme qui affiche la chaine argv[0]
puis tester d'afficher aussi argv[1] et argv[2]...
Garder les lignes pour afficher argv[x] dans votre programme
./param2 un deux trois
Aide:
printf ("%s\n",argv[0]);
donc ça sert aussi argv !! v comme value !
Rque: si vous avez eu le message d'erreur de segmentation core dump ! c'est que vous utilisez des argv[ ] qui n'existe pas donc.. ça plante, il faut savoir si il existe grâce a argc
dans un répertoire
exercice8 exercice8.c
argc : contient la valeur entière de paramètre reçu par la fonction.
argv[0 ....x] : sont des chaînes contenant les paramètres si ils existent...
Écrire un programme que si on ne passe pas un argument il retourne EXIT_FAILURE et indique a l'utilisateur qu'il faut donner un paramètre, sinon il retourne EXIT_SUCCESS et dit bonjour !
Algo:
Variables
argc est un entier contenant le nombre de paramètre passé (1 si aucun , 2 si un .. 3 si deux ..)
argv contient les chaines de caracteres en ASCII en fonction de argc
Debut param (argc,argv)
Si argc different de 2 alors
Debut Si
afficher "Veuiller entrer un paramètre svp "
fin si retourner EXIT_FAILURE
Sinon
Debut Sinon
afficher "le parametre est :"
afficher argv[1]
fin sinon retourner EXIT_SUCCESS
Nous donnons la traduction en code C pour montrer les syntaxes.
code c de exercice8.c
/********************************/
/* Code passage de paramètres */
/* (c)2021 18/10 Bogt */
/********************************/
#include<stdlib.h>
#include<stdio.h>
int main(int argc, char **argv)
{
if (argc!=2) /* different est!= en C!! */
{
printf("Veuiller entrer un paramètre svp \n");
return EXIT_FAILURE;
}
else
{
printf("le parametre est du programme %s :%s \n",argv[0],argv[1]);
}
return EXIT_SUCCESS;
}
dans un répertoire exercice9 exercice9.c
Ecrire un programme qui fonctionne comme ci dessous
Donner l'algorithme en français param0.algo et param0.c en C
./exercice9
Veuillez rentrer votre nom svp
./exercice9 Dorian
Bonjour Maître Dorian !
dans un répertoire exercice10 exercice10.c
Nous avons découvert la condition Si (if)
if (argv [1][0]=='D') printf ("ca commence par D\n");
ici argv[1][0] est le premier caractère indice 0 de la chaine argv[1]
Et == est la comparaison des 2 éléments , un test donc , si = seul !! c'est une affectation
Ecrire un programme exercice10.c et exercice10.algo qui ne dira bonjour Maître qu'a DORIAN comme ci dessous:
./exercice10 sylvain
Bonjour Sylvain
./exercice10
Donnez moi un parametre svp
./exercice10 DORIAN
Bonjour Maître Dorian!
Aide :
Dans un if on peut utiliser les fonctions ET, OU, OU EX, not
pour tester tous les caractères de DORIAN
if ((argv [1][0]=='D') && (argv [1][1]=='O')) printf ("ça commence par D et O \n");
ici le
&& est le ET logique
|| est le OU logique
! pour le NOT , le non, le complément
dans un répertoire exercice11 exercice11.c
Pour transformer une chaîne de caractères en valeur entière on dispose de la fonction atoi().
Lire le man de atoi , lire a to i , transforme des codes ASCII en Integer ,ou lire ASCII TO INTEGER
normalement vu en cours mais la solution est donnée ci dessous , pour faire avancer !
Écrire un code qui affiche le résultat de
atoi("Bonjour");
et
atoi("2018");
exercice11.c dans le répertoire exercice11
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char ** argv)
{
int nb_entier;
nb_entier = atoi ("bonjour"); /* atoi , lire ascii to integer */
printf("%d \n",nb_entier);
nb_entier =atoi("2025");
printf("%d \n",nb_entier);
}
# on teste
bruno@elliott:~/Works/langage_C/atoi$ gcc atoi.c -o atoi
bruno@elliott:~/Works/langage_C/atoi$ ./atoi
0
2025
bruno@elliott:~/Works/langage_C/atoi$
répertoire exercice12 addition.c
qui va se comporter comme ci dessous:
./addition 3 4
7
./addition
Entrer 2 paramètres svp.
./addition 4
Entrer 2 paramètres svp.
répertoire exercice13 soustraction.c
Comme dans la question 12.
répertoire exercice14 multiplication.c
Comme dans la question 12.
répertoire exercice15 division.c
Comme dans la question 12.
analyse_octets.c
#include <stdio.h>
#include <stdlib.h>
// Affiche les codes hexadécimaux et décimaux de chaque octet d'une chaîne
void print_bytes(const char *str) {
int i = 0;
printf("Analyse de la chaîne : \"%s\"\n", str);
printf("Position | Octet (hex) | Octet (dec) | Type\n");
printf("-------------------------------------------\n");
while (str[i] != '\0') {
unsigned char c = (unsigned char)str[i];
printf("%7d | 0x%02X | %3d | ", i, c, c);
if (c <= 127) {
printf("ASCII simple\n");
} else {
printf("Caractère > 127 (ASCII étendu ou UTF-8)\n");
}
i++;
}
}
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage : %s chaine\n", argv[0]);
return EXIT_FAILURE;
}
print_bytes(argv[1]);
return EXIT_SUCCESS;
}
Exemple de l'analyse de la chaîne de caractère "Lycée Caroline Dorian"
bruno@elliott:~/Works/langage_C/utf8decoder/analyse_octets$ ./analyse_octets "Lycée Caroline Dorian"
Analyse de la chaîne : "Lycée Caroline Dorian"
Position | Octet (hex) | Octet (dec) | Type
-------------------------------------------
0 | 0x4C | 76 | ASCII simple
1 | 0x79 | 121 | ASCII simple
2 | 0x63 | 99 | ASCII simple
3 | 0xC3 | 195 | Caractère > 127 (ASCII étendu ou UTF-8)
4 | 0xA9 | 169 | Caractère > 127 (ASCII étendu ou UTF-8)
5 | 0x65 | 101 | ASCII simple
6 | 0x20 | 32 | ASCII simple
7 | 0x43 | 67 | ASCII simple
8 | 0x61 | 97 | ASCII simple
9 | 0x72 | 114 | ASCII simple
10 | 0x6F | 111 | ASCII simple
11 | 0x6C | 108 | ASCII simple
12 | 0x69 | 105 | ASCII simple
13 | 0x6E | 110 | ASCII simple
14 | 0x65 | 101 | ASCII simple
15 | 0x20 | 32 | ASCII simple
16 | 0x44 | 68 | ASCII simple
17 | 0x6F | 111 | ASCII simple
18 | 0x72 | 114 | ASCII simple
19 | 0x69 | 105 | ASCII simple
20 | 0x61 | 97 | ASCII simple
21 | 0x6E | 110 | ASCII simple
bruno@elliott:~/Works/langage_C/utf8decoder/analyse_octets$
Expliquer ce qu'est ASCII - ASCII étendu et UTF8
Pseudo Code de analyse_octets
Algorithme ANALYSER_CHAINE_OCTETS
Début
// Vérifier la présence d’un argument
Si le nombre d’arguments < 2 alors
Afficher "Usage : ./programme chaîne"
Quitter avec un code d’échec (EXIT_FAILURE)
Fin Si
chaine ← argument[1]
i ← 0
Tant que chaine[i] ≠ caractère de fin ('\0') faire
octet ← valeur entière non signée de chaine[i]
Afficher "Position : ", i
Afficher "Octet (hex) : ", octet en hexadécimal
Afficher "Octet (déc) : ", octet en décimal
Si octet ≤ 127 alors
Afficher "Type : ASCII simple"
Sinon
Afficher "Type : octet non-ASCII (UTF-8 ou étendu)"
Fin Si
i ← i + 1
Fin Tant que
Quitter avec un code de succès (EXIT_SUCCESS)
Fin
répertoire exercice16 exercice16.c
le goto en C , est souvent ignoré car il fait écrire un code mal structuré.
Impose de mettre des étiquettes !!
Nous le voyons ici , mais nous ne le reverrons sûrement plus jamais!
/********************************/
/* Code goto */
/* (c)2021 18/10 Bogt */
/********************************/
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int compteur =0;
etiquette:
printf("%d \n",compteur);
compteur=compteur+1;
if (compteur==10) goto dehors;
goto etiquette;
dehors:
return EXIT_SUCCESS;
}
Donner le pseudo langage et l'organigramme de ce programme à l'aide de monia.