Bonjour avec prénom en majuscules, date et heure
Le programme doit afficher Bonjour sur l'écran, demander un prénom.
Il affiche ensuite sur la ligne suivante la date et l'heure puis écrit
"au revoir" suivi du nom de la personne en majuscules. De façon plus
précise, on essaiera de respecter l'initiale majuscule du mot Bonjour,
on affichera de la façon la plus simple, en utilisant si possible une
chaine de caractères. Le programme affichera si possible
"Quel est votre prénom ?" sur la même ligne que le mot Bonjour ;
le curseur restera un espace après le signe ? pour la saisie du prénom.
Une fois la réponse de l'utilisateur entrée, la date et l'heure seront
écrites avec le message de fin sur la même ligne. S'il n'est pas simple
de présenter la date sous forme lisible, on pourra laisser la date avec
indication du mois sous forme numérique compacte (1 pour Janvier, 2 pour février etc.).
Exemple d'exécution :
si monsieur TEST lance le programme à 11h30:12 le 12/01/1992,
voici ce qui apparait à l'écran :
Bonjour. Quel est votre prénom ? Test
Le 12 janvier 1992 à 11:30 ; au revoir, TEST.
L'algorithme correspondant ne présente aucune difficulté.
Il fait référence aux fonctions date, heure et maju. On aurait pu
écrire date() et heure() au lieu de date et heure, MCRIRE au lieu
de MECRIRE (qui signifie, rappelons "écrire sur la même ligne sans
passer à la ligne suivante") pour garder autant de lettres que dans
le mot ECRIRE, mais cela est peut-être trop technique.
Nous avons préféré la forme simple suivante
* Algorithme de BONJOUR
ECRIRE " Bonjour "
MECRIRE " Quel est votre prénom ? "
LIRE pren
ECRIRE "Le ",date," à ",heure," au revoir, ",maju(pren)
La solution Rexx peut rester sous forme de "source", car il n'y a
pas de compilation en Rexx ; la précompilation ajouterait 1k au bout
du fichier. L'option E dans date signife format Européen (car Rexx dispose
d'une dizaine d'options pour afficher l'heure). On notera la différence
entre say et call charout qui affichent avec ou sans passage à la ligne
suivante. L'instruction pull, qui est une abréviation et une adaptation
de parse upper pull traduit automatiquement en majuscules.
/* BONJOUR.REX */
call charout , "Bonjour. Quel est votre nom ? "
pull pren
say "le" date(E) "à" time() "au revoir," pren
La fonction date qui possède de nombreuses options ne permet pas
toutefois d'obtenir les mois en lettres. Pour passer des nombres
aux lettres, plusieurs méthodes sont possibles. La plus simple
consiste à utiliser une structure des cas, la seconde à indexer
les noms de mois dans une structure (tableau, phrase etc.) ;
nous présentons ici les deux solutions.
La première utilise la structure de cas
Aux cas où
cas moi = 1
mois <-- 'Janvier'
cas moi = 2
mois <-- 'Février' etc.
cas moi = 12
mois <-- 'Décembre'
autres cas
mois <-- ""
écrire "numéro de mois invalide"
Fin des Cas
Une fois traduite en Rexx, cette structure de cas résoud le
probléme avec la première solution :
parse value date(E) with jr '/' moi '/' an
select
when moi = 1 then mois = 'Janvier'
when moi = 2 then mois = 'Février'
when moi = 3 then mois = 'Mars'
etc.
when moi = 11 then mois = 'Novembre'
when moi = 12 then mois = 'Décembre'
end
Une solution plus concise et plus élégante consiste à définir
une phrase dont les mots sont les noms des mois ; la deuxième
solution Rexx est alors
NomDesMois = 'Janvier Février Mars Avril Mai Juin Juillet Août'
NomDesMois = NomDesMois 'Septembre Octobre Novembre Décembre'
parse value date(E) with jr '/' moi '/' an
mois = word(NomDesMois,moi)
Le programme Turbo Pascal correspondant est nettement plus long :
il n'existe pas de primitive donnant l'heure ou la date et la
fonction upper ne travaille que sur un caractère à la fois.
Contrairement au problème de Comar, toutes les instructions
sont écrites dans le programme principal, sans aucune fonction
ni procédure.
program BONJOUR_en_PASCAL ;
uses dos ; (* pour Date et Heure *)
var pren : string ; (* contient le prénom *)
ic : integer ; (* indice de boucle *)
an,mois,jour,js : word ;
moisc,jourc : string ; (* équivalents caractères *)
heur,mini,sec,cent : word ;
heurc,minic : string ; (* équivalents caractères *)
BEGIN (* bonjour_en_pascal *)
(* demande du prénom *)
writeln('Bonjour ') ;
write('Quel est votre nom ? ') ;
readln(pren) ;
(* passage en majuscule de chacune des lettres de PREN *)
for ic := 1 to length(pren) do begin
pren[ic] := upcase(pren[ic])
end ; (* fin pour IC *)
(* on récupère la date grâce à l'unité Dos *)
GetDate(an,mois,jour,js) ;
GetTime( heur,mini,sec,cent ) ;
(* conversion en caractère : il faut éventuellement rajouter 0 pour avoir
un cadrage homogène sur 2 caractères *)
str(jour,jourc) ; if jour < 10 then jourc := '0' + jourc ;
str(mois,moisc) ; if mois < 10 then moisc := '0' + moisc ;
str(heur,heurc) ; if heur < 10 then heurc := '0' + heurc ;
str(mini,minic) ; if mini < 10 then minic := '0' + minic ;
(* affichage final*)
writeln('Le ', jourc,'/',moisc, '/', an, ' à ', heurc,':',minic, ' au revoir, ',pren)
END. (* bonjour_en_pascal *)
Toutefois, avec les bonnes procédures dans le fichier inclus Bonjour.Ins,
(à savoir jour, mois, an, heure, minute et maju) on aurait pu réaliser
un programme beaucoup plus proche de l'algorithme et de toutes façons
beaucoup plus lisible. Un modèle possible d'un tel programme en Turbo
Pascal (version 5 ou supérieure) pourrait être le suivant. On appréciera
le fait qu'une seule variable est visible globalement (pren), qui est
la seule à figurer explicitement dans l'énoncé.
PROGRAM BONJOUR_en_PASCAL ;
uses dos ; (* pour Date et Heure *)
(*$I Bonjour.Ins *)
Var pren : string ; (* contient le prénom *)
BEGIN (* bonjour_en_pascal *)
writeln('Bonjour ') ;
write('Quel est votre nom ? ') ;
readln(pren) ;
writeln('Le ',jour,'/',mois,'/',an,' à ',heure,':',minute,' au revoir, ',maju(pren) )
END. (* bonjour_en_pascal *)
En Pascal, pour afficher le nom du mois plutôt que son numéro, on
peut aussi utiliser un tableau constant de chaînes de caractères
grâce à la déclaration suivante
const tab : array[1..12] of string[10] = ('Janvier','Février','Mars','Avril','Mai',
'Juin',Juillet','Août','Septembre','Octobre','Novembre','Décembre')
on accède alors au nom du mois grâce à l'expression TableauMois[ mois ].
En Awk, les fonctions date et heure n'existent pas. Toutefois, ctime()
renvoie la date et l'heure dans un format particulier que l'on réarrange
très facilement avec les variables $i. Le deuxième mot de ctime() est en
effet le numéro du mois, le troisième mot correspond au jour dans le mois etc.
# BONJOUR.AWK
BEGIN {
print "Bonjour "
printf "Quel est votre nom ? " ; getline pren < "CON"
$0 = ctime()
date = $3 " " $2 " " $NF
heure = substr($4,1,5)
print "le " date " à " heure " au revoir," toupper(pren)
} # fin du programme ; pas de parcours de fichier ni de section END
A priori, pour utiliser cette solution AWK, il faut, à l'exécution,
donner le nom d'un fichier de données car un programme AWK travaille
en standard avec toujours au moins un fichier de données. On peut
lever cette restriction à condition de rajouter en début de programme
l'instruction ARGV[1] = "", ou même ARGV="" si la version de Awk le
permet mais cela n'a vraiment que peu de rapports avec notre algorithme.
Cette instruction a pour but de mettre à vide la variable ARGV qui
contient les arguments passés au programme, c'est-à-dire
traditionnellement une ou plusieurs spécifications (peut être ambigue) de fichiers.
Une version unix du meme programme est peut differente :
# BONJOUR.AWK
BEGIN { ARGV[1] = ""
print "Bonjour " ; printf "Quel est votre nom ? "
}
{ pren = $0
"date " | getline
date = $3 " " $2 " " $NF ; heure = substr($4,1,5)
print "Le " date " à " heure " au revoir, " toupper(pren)
exit
}
Pour obtenir en Awk le nom du mois en toutes lettres, on peut
utiliser la même technique qu'en Rexx :
NomDesMois = "Janvier Février Mars Avril Mai Juin Juillet Août"
NomDesMois = NomDesMois "Septembre Octobre Novembre Décembre"
$0 = NomDesMois
# moi est le numéro, mois le nom
mois = $moi
La solution Dbase ressemble fortement à la solution algorithmique.
On notera la contraction du Mcrire et du Lire en une seule demande
via ACCEPT. Cette contraction est délicate : ce qu'on a le droit
de mettre après ACCEPT n'est pas exactement ce qu'on peut mettre
après un ? ou un SAY. Ainsi, ? A, B+C où A, B et C sont des chaînes
de caractères est correct (la distinction entre l'affichage conjoint
B, C et l'affichage de la concaténation B+C est subtile) mais
ACCEPT A,B+C TO ... est incorrect.
La fonction upper en Dbase travaille sur des chaînes. Dbase ayant
été bien francisé (même si il reste certaines questions en français
auxquelles il faut répondre par Y ou N dans la version Dbase3plus),
upper("é") renvoie bien "E", contrairement au Pascal qui renvoie "é"
dans ce cas. On retrouve ce problème quand on trie des mots avec des
caractères accentués. Si le tri utilise l'ordre ascii, alors mille
sera placé avant médecin, d'où un tri pour le moins surprenant !
* BONJOUR en DBASE
? " Bonjour "
ACCEPT "Quel est votre nom ? " to pren
? "Le ",date()," à ",time()," au revoir, ",upper(pren)
En C, on retrouve un programme similaire au Pascal. Cette-fois ci,
on dispose de fonctions dans des bibliothèques standards, auxquelles
on accède par les instructions #include. La lecture et l'écriture en
C peuvent être formatées (ou seulement typées), par exemple comme ici
avec le spécificateur de format %s (ce que rappelle le f de printf
et scanf). Ce formatage peut donner lieu à des conversions surprenantes.
L'entête permet d'utiliser les fonctions des bibliothèques standard pour
les entrées, les chaînes et le temps :
/* Bonjour en Turbo C */
#include
#include
#include
Le reste du programme utilise les fonctions en bibliothèque :
main() { char pren[80] ; struct tm *now ; long nbsec ;
printf("Bonjour\n");
printf("Quel est votre prénom ? ");
scanf("%s",pren) ; strupr(pren) ;
time(&nbsec) ; now = localtime(&nbsec) ;
printf("le %02d/%02d/%02d à %02d:%02d au revoir, %s",
w->tm_mday, now->tm_mon, now->tm_year,
now->tm_hour,now->tm_min, pren) ;
} /* fin du programme principal */
La solution en Apl est relativement courte aussi :
[0] BONJOUR ; MSG ; PREN
[1] „ Exemple classique d'E/S et de conversion sur chaîne
[2] ` C MSG C 'Bonjour. Quel est votre prénom ?'
[3] PREN C `
[4] PREN C (‘ MSG) {CARSPECIAUX 70 \f "Lucida Bright Math Symbol"}PREN
[5] DATE , ' - au revoir,' , (MAJU PREN) , '.'
où la fonction MAJU est définie par :
[0] Z C MAJU X ; VS ; NBX
[1] „ Passage en majuscule de X
[2] LETTRES C {CARSPECIAUX 127 \f "Lucida Bright Math Symbol"}AV[ (62+VS),89+VSC26]
[3] NBX C LETTRES {CARSPECIAUX 105 \f "Symbol"} X
[4] Z C LETTRES[NBX - 26 x NBX > 26 ]
Quelques explications s'imposent : Z C dans la ligne zéro c'est-à-dire dans
l'en-tête de la fonction MAJU signifie que le résultat est explicite et donc
renvoyé. X est le paramètre de la focntion. Les variables VS et NBX sont locales ;
par contre LETTRES est globale. boiteAV est le vecteur atomique ; il représente
l'ensemble des caractères. LETTRES contient ici les majuscules de A à Z puis
les minuscules de a à z. NBX contient les codes correspondant aux lettres
du paramètre X. La ligne 3 vient retirer aux codes des lettres minuscules
la valeur 26 de façon à ce que l'indexation dans LETTRES redonne les majuscules.
De même, la fonction DATE est ({CARSPECIAUX 127 \f "Lucida Bright Math Symbol"}TS
est un vecteur système qui contient le mois, le jour etc. sous forme numérique)
[0] Z {CARSPECIAUX 67 \f "Lucida Bright Math Symbol"} DATE ; JOUR ; NUMMOIS ; CHMOIS ; AN
[1] JOUR {CARSPECIAUX 67 \f "Lucida Bright Math Symbol"} {CARSPECIAUX 127 \f "Lucida Bright Math Symbol"}TS[3]
[2] NUMMOIS {CARSPECIAUX 67 \f "Lucida Bright Math Symbol"} {CARSPECIAUX 127 \f "Lucida Bright Math Symbol"}TS[2]
[3] AN {CARSPECIAUX 67 \f "Lucida Bright Math Symbol"} {CARSPECIAUX 127 \f "Lucida Bright Math Symbol"}TS[1]
[4] CHMOIS {CARSPECIAUX 67 \f "Lucida Bright Math Symbol"} MOIS[NUMMOIS;]
[5] Z {CARSPECIAUX 67 \f "Lucida Bright Math Symbol"} 'Le ', (èJOUR) , ' ' , MOIS , ' ' ,èAN
Ces fonctions APL ne font pas à proprement parler partie du programme
correspondant à l'exemple. Elles sont seulement présentes en même dans
la zone de travail ("WorkSpace"). Apl ne travaille pas seulement comme
un langage mais aussi comme un environnement.
La solution en Turbo Prolog définit aussi plusieurs prédicats
(mois et hello) regroupés dans une même application. Le choix du
prédicat mois et de la variable Mois est volontairement ambigu.
On appréciera la lisibilité et la facilité de remplacement du
numéro de mois par son équivalent chaîne de caractères grâce à
l'unification. Pour ceux qui ne connaissent pas Turbo Prolog,
rappelons que upper_lower(x,y) a trois niveaux d'utilisation :
- si x est donné et y libre, alors y est lié à l'équivalent minuscule de x
- si x est libre et y donné, alors x est lié à l'équivalent majuscule de y
- si x et y sont donnés, upper_lower renvoie vrai si x et y sont égaux, sans
distinction de majuscules ou minuscules ; sinon upper_lower renvoie faux.
Pour correspondre au "typage" de Turbo Prolog, on commence
par les "pseudo déclarations"
predicates
mois(integer,string)
hello
goal
hello.
Le programme véritable commence ensuite, précédé de l'instruction "clauses".
clauses
mois(1,"Janvier").
mois(2,"Février").
mois(3,"Mars").
mois(4,"Avril").
mois(5,"Mai"). /* etc. */
hello :-
clearwindow,
write(" Bonjour. Quel est ton prénom "),
readln(Pren),
upper_lower(PrenMaj,Pren),
date(An,Mois,Jour),
mois(Mois,ChMois),
write("Le ",Jour," ",ChMois," ",An," bonsoir,",PrenMaj)
. /* fin de hello */
Nous présentons aussi quelques versions simplifiées de Bonjour.
La première est en assembleur. En assembleur sous MSDOS, on peut
générer de fichiers de type Com ou Exe. Les programmes correspondants
sont, une fois assemblés très courts, même si leur texte est long,
puisqu'il faut tout détailler. On donne tout d'abord une version
ultra-courte qui affiche seulement "Bonjour" par un programme Exe.
; Solution assembleur minimale générant un .EXE (705 octets)
; on affiche seulement "Bonjour" à l'écran
DSEG SEGMENT ; en Assembleur, les variables sont
MESSAGE DB 'Bonjour$' ; rangées dans un segment à part des
DSEG ENDS ; instructions du programme.Le symbole
; $ indique la fin de la chaine.
SSEG SEGMENT STACK ; les fichiers de type .EXE imposent
DW 80 DUP ( 'GH' ) ; une " pile "
SSEG ENDS
BONJOUR SEGMENT ; les instructions du programme sont
; aussi à mettre dans un segment.
ASSUME CS : BONJOUR, DS : DSEG
; il faut alors indiquer où trouver
; les données, les instructions
MAINPP PROC FAR ; le programme principal doit être
; défini comme une procédure
DEBUT:
PUSH D ; ces lignes initialisent les registres
SUB AX, AX ; de façon à bien pointer les segments
PUSH AX
MOV AX, DSEG
MOV DS, AX
; voici l'affichage : on utilise la fonction 9 du DOS (via
; l'interruption 21 après avoir indiqué où commence la chaine
; de caractères.
MOV DX, OFFSET MESSAGE
MOV AH, 09
INT 21H RET MAINPP ENDP
BONJOUR ENDS
END DEBUT ; on indique où doit démarrer le programme.
Le même affichage avec un .COM est encore plus court, puisqu'il ne
fait que 19 octets soit une dizaine d'octets de plus que le mot
'Bonjour'. Sigalons qu'un programme équivalent compilé à partir
de Pascal ou C prendrait au moins un ou deux kilo octets ;
passer de 19 octets à 2048 octets représente une grande différence de taille.
; Solution minimale générant un .COM (19 octets)
BJR2 SEGMENT
ASSUME CS:BJR2,DS:BJR2
ORG 100H
DEB: JMP DEBUT
MSG DB 'Bonjour$'
DEBUT: MOV DX,OFFSET MSG
MOV AH,9
INT 21H
RET
BJR2 ENDS
END DEB
Une solution plus complète qui lit le nom et le réaffiche est déjà
plus longue en termes de lignes source sans être très lisible ;
par exemple, il faut connaitre la notion d'interruption
(notamment celle numéro 20), savoir ce qu'est une fonction
Dos ou Bios (comme la fonction 9) pour découvrir où se situe
la traduction du mot LIRE de l'algorithme.
; Solution détaillée : on dit bonjour, on demande le nom,
; ---------- on dit "au revoir" suivi du nom.
HLO SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:HLO,DS:HLO,ES:HLO,SS:HLO
ORG 100H
DIB:
JMP DIBUT
CR DB 0DH,'$'
LF DB 0AH,'$'
QRY DB 'Quel est votre nom ? $'
PREN DB 8, 10 DUP('$')
FINCH DB 'Au revoir, $'
DOLAR DB '$'
POINT DB '.$'
DIBUT:
; demande du nom : on pose la question
MOV DX,OFFSET QRY
MOV AH,9
INT 21H
; demande du nom : lecture de la réponse (variable PREN)
MOV DX,OFFSET PREN
MOV AH,0AH
INT 21H
; demande du nom : --> on remplace le caractère Enter par
; Dollar pour utiliser la fonction 9 de l'int 21
MOV BX,DX
MOV CX,[BX]+1
MOV CH,0
ADD BX,2
ADD BX,CX
MOV AL,'$'
MOV [BX],AL
; demande du nom : on passe à la ligne suivante
MOV DX,OFFSET CR
MOV AH,9
INT 21H
MOV DX,OFFSET LF
MOV AH,9
INT 21H
; affichage du message de fin
MOV DX, OFFSET FINCH
MOV AH,9
INT 21H
; réaffichage de la réponse (variable PREN)
MOV CX,4
MOV DX,OFFSET PREN
ADD DX,2
MOV AH,9
INT 21H
; passage à la ligne suivante
MOV DX,OFFSET POINT
MOV AH,9
INT 21H
MOV DX,OFFSET CR
MOV AH,9
INT 21H
MOV DX,OFFSET LF
MOV AH,9
INT 21H
; retour au dos
MOV AH,4CH
INT 21H
HLO ENDS
END DIB ; fin du programme assembleur
Pour les solutions en Lisp, on se méfiera des différents dialectes,
surtout au niveau des entrées et des sorties. Ainsi, en AutoLisp
(Lisp pour AutoCad) on peut lire des chaînes, des points, des
distances, des angles très simplement. La fonction print
d'AutoLisp ne renvoie pas la même chose que la fonction
print de Lelisp, etc. Setq ne correspond pas vraiment à une
affectation mais réalise une liaison qui est en proche, princ
écrit une chaîne de caractères sans passer à la ligne, strcat
réalise la concaténation, terpri envoie une ligne vide au terminal.
De même, en LeLisp, read lit une chaine et renvoie la valeur lue.
Un Bonjour simplifié possible en AutoLisp est
(defun C:bonjour() ; Lisp pour Autocad
(setq pren (getstring " Bonjour.Quel est votre prénom ? "))
(princ (strcat " Au revoir, " pren ".")) (terpri)
)
Et en LeLisp
(defun bonjour()
(print "Bonjour. Quel est votre prénom ? ")
(setq pren (read) )
(print "Au revoir, " pren ".")
)
Pour la version simplifiée de bonjour en Cobol : on a
utilisé volontairement un branchement via l'instruction
PERFORM. Certains raccourcis (l'absence de OF MOIS dans
l'instruction MOVE MOIS notamment) sont aussi volontaires.
IDENTIFICATION DIVISION.
PROGRAM-ID. BONJOUR.
AUTHOR. HUNAULT.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 REPONSE.
05 PREN PIC X(20).
77 INDM PIC S9(4) COMP.
01 LIGNEDATE.
05 FILLER PIC XXXX VALUE 'Le '.
05 JJ PIC 99.
05 FILLER PIC XX VALUE SPACES.
05 MM PIC X(10).
05 FILLER PIC XX VALUE '19'.
05 AA PIC 99.
01 TABLEAUMOIS.
05 LIBEL.
07 FILLER PIC X(10) VALUE 'Janvier '.
07 FILLER PIC X(10) VALUE 'Février '.
07 FILLER PIC X(10) VALUE 'Mars '.
07 FILLER PIC X(10) VALUE 'Avril '.
07 FILLER PIC X(10) VALUE 'Mai '.
etc.
05 ZONEDAT REDEFINES LIBEL.
07 ELEM OCCURS 12 PIC X(10).
01 DAT.
05 AN PIC 99.
05 MOIS PIC 99.
05 JOUR PIC 99.
PROCEDURE DIVISION.
PROG.
DISPLAY 'Début'.
DISPLAY 'Bonjour quel est votre nom ? '.
ACCEPT PREN.
PERFORM PROG-JOUR.
DISPLAY LIGNEDATE ', bonsoir ' PREN.
STOP RUN.
PROG-JOUR.
ACCEPT DAT FROM DATE.
MOVE AN OF DAT TO AA IN LIGNEDATE.
MOVE JOUR OF DAT TO JJ IN LIGNEDATE.
MOVE MOIS TO INDM.
MOVE ELEM (INDM) TO MM.
Le texte qui suit correspond à un Bonjour en Smalltalk
(nous avons utilisé des positionnements curseur de façon à
obtenir toujours l'affichage toujours au même endroit, car
sinon il dépend de la position de la souris au moment où est lancé le programme)
Bonjour " Exemple de commentaire, lire, écrire et affectation "
| pren |
Cursor offset: 140 @ 150.
pren := Prompter
prompt: ' Bonjour. Quel est ton prénom ? '
default: ''.
pren := ' Merci. Au revoir ' , (pren asUpperCase), ' ' ,
(Date today) printString.
Cursor offset: 140 @ 300.
Menu message: pren.
Un tel programme ne peut s'utiliser seul. Il est en fait considéré
comme un sous programme (une méthode) liée à une classe d'objets. Par
exemple, nous l'avons associé à un objet de type démonstration. Si
DemoUno est une instance d'un tel objet, l'envoi du message DemoUno
Bonjour lancera notre "programme". Le stockage du texte du programme
ne se fait pas dans un fichier mais dans "l'image" du lanagage Smalltalk
(contrairement à Apl, tout le langage est stocké, et non pas seulement
les fonctions utilisateur). Signalons au passage que le texte source
de toutes les parties de Smalltalk est accessible et modifiable.
En ADA , nous définirons une fonction uppercase à l'intérieur d'un
"module" et notre programme principal sera une "procédure". Ada sait
bien gérer la compilation séparée, sait même dans certains cas utiliser
un même code (dit "générique") pour traiter des structures semblables
(par exemple des tableaux) dont les éléments sont de même type
(tableaux d'entiers et tableaux de chaines, par exemple).
-- Bonjour.Ada
with text_io ; use text_io ;
procedure bonjour is
subtype id is string(1..5) ;
nom : id ;
function uppercase(chaine : in id ) return id is
c : character ; i : integer ; ch : id ;
begin -- uppercase
for i in chaine'range loop -- ne pas mettre for i in 1..chaine'length
-- a cause d'un appel uppercas(ch(3..9)) possible
c := chaine(i) ; put(c) ;
if c >= 'a' and c <= 'z'
then ch(i) := 'M' ;
else ch(i) := c ;
end if ;
end loop ;
return ch ;
end uppercase ;
begin -- bonjour
put("Bonjour, quel est votre nom ? (sur 5 carac) ");
get(nom) ;
put("Merci. Le ");
put(", au revoir, "); put( uppercase(nom) ) ;
put_line(".");
end bonjour ;