Partage

[Exercices] Venez vous entraîner !

Ce mois: Parseur de fonctions mathématiques

5 juillet 2008 à 12:20:42

J'ai juste une remarque : il n'y a pas de balise code sur main.cpp ;) .
5 juillet 2008 à 12:40:18

@Scaerloc: Tu peux toujours aller plus loin pour toi. La solution proposée sera par contre limitée à ce qui est demandé.

@Gymnopaul: Corrigé. Merci.
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
5 juillet 2008 à 13:57:51

Le code du corrigé n'est pas portable, le fichier temporaire n'est pas suprrimé sous Vista.
Et la variable retour devrait être de type int et pas bool, et donc le type de retour de la fonction gereArguments devrait être int aussi.
FaQ : Fr | En 1 2 | C++11 | Template || Blog : Deloget | C++|Boost--Dev | C++Next | GotW || Installer Boost
5 juillet 2008 à 14:21:21

effectivement je me suis trompé pour le type de retour.

Quand au système de suppression je m'étais trompé dans la première version et je croyais avoir édité le fichier:
Il faut le remplacer par :
#ifdef _WIN32 // Si c'est Windows on utilise del
    char strDestruct[100] = "del ";
    int longueurBase = 4;
    #elif __unix__ // Si on est sur un MAC ou un Linux on utilise rm
    char strDestruct[100] = "rm ";
    int longueurBase = 3;
    #else
        #warning Ce programme ne marche que sous Windows, Linux ou Macintosh
    #endif
5 juillet 2008 à 14:55:21

Ou tout simplement: http://c.developpez.com/faq/?page=fich [...] S_delete_ANSI

PS: trainent des chaines copiées, et surtout une lecture sur eof.
C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
5 juillet 2008 à 15:28:32

Et... Est ce qu'on aura des appréciation de ce qu'on a fait par MP ? Histoire de connaître les erreurs que l'on fait ?
6 juillet 2008 à 20:56:15

@lmghs: Merci, je fais les modifications.

@congelli501: Je n'ai malheureusement pas le temps de répondre à tout le monde de manière personelle.
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
10 juillet 2008 à 20:19:10

Mise à jour de la réponse de l'exercice.
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
11 juillet 2008 à 17:29:43

Tu pourrais nous donner les réponses qu'on est censé obtenir sur l'article de wikipédia ? Avec le contenu exact que tu a pris, si possible. A la limite le fichier qui le contient, histoire de pas spamer le forum. Ca nous permettra de contrôler avant de l'envoyer. Parce que je me sens pas de compter à la main les caractères de l'article pour savoir si mon programme a bon ^^
11 juillet 2008 à 18:13:19

Je dirais qu'on s'en fout un peu mais si tu y tiens vraiment, voilà à quoi j'arrive :

3035 mots
16346 caractères (sans espace)
19145 caractères
289 paragraphes
483 lignes
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
15 juillet 2008 à 22:17:15

2ème Exercice du mois de juillet 2008



Cet exercice est plus difficile que le dernier que celui du début du mois


Nom : Interpréteur BrainFuck
Sujet : Fichiers, pointeurs


Introduction



Je sais pas si vous avez déjà fait un tour sur Wikipédia pour y regarder la liste des différents langages de programmation. Il y en a un qui me plaît particulièrement, le BrainFuck.
C'est un langage minimal mais qui est néanmoins Turing-complet (i.e. vous pouvez donc tout programmer avec) et comme il est très simple, je vous propose de réaliser un interpréteur BrainFuck afin de pouvoir exécuter des codes-sources écrits dans ce splendide langage :p

Description du langage



Le Brainfuck est constitué de 3 éléments.

1) Un tableau de 30'000 octets initialement tous à 0. (En C++ un char = un octet)
2) Un pointeur sur une des cases du tableau initalement à la première case du tableau.
3) Un jeu de 8 instructions (mots-clés) permettant de "jouer" avec le pointeur.

Les instructions sont les suivantes:

Symbole Action
> Déplace le pointeur d'une case vers la droite
< Déplace le pointeur d'une case vers la gauche
+ Augmente de 1 la valeur de l'octet pointé
- Décrémente de 1 la valeur de l'octet pointé
. Affiche la valeur de l'octet pointé dans la console.
, Récupère un caractère depuis la console et met la valeur dans l'octet pointé
[ saute à l'instruction après le ] correspondant si l'octet pointé est à 0
] retourne à l'instruction après le [ si l'octet pointé est différent de 0


Si le pointeur sort du tableau, on le remet à l'autre bout. Tous les autres caractères dans le code-source sont ignorés.

Voilà, vous connaissez tout du BrainFuck. (Plus simple que le C++ non ?) Voici un code-source :

++++++++++
[                   Boucle initiale qui affecte des valeurs utiles au tableau
   >+++++++>++++++++++>+++>+<<<<-
]
                    à la sortie de la boucle le tableau contient: 0  70  100  30  10
>++.                      'H'    = 72  (70  plus 2)
>+.                       'e'    = 101 (100 plus 1)
+++++++.                  'l'    = 108 (101 plus 7)
.                         'l'    = 108
+++.                      'o'    = 111 (108 plus 3)
>++.                      espace = 32  (30  plus 2)
<<+++++++++++++++.        'W'    = 87  (72  plus 15)
>.                        'o'    = 111
+++.                      'r'    = 114 (111 plus  3)
------.                   'l'    = 108 (114 moins 6)
--------.                 'd'    = 100 (108 moins 8)
>+.                       '!'    = 33  (32  plus  1)
>.                        nouvelle ligne = 10


Vous aurez reconnu le célèbre "Hello World!"

L'exercice



L'exercice de ce mois consiste à écrire un interpréteur BrainFuck. C'est-à-dire un programme qui recoit un code-source BF en argument et exécute le code dans le fichier.

./interptreteur hello.b
---- Lancement de l'interpreteur -----
Hello World !
---- Fin du programme -----


Si il y a des erreurs dans le code-source, votre interpréteur devra les indiquer.

./interptreteur hello.b
---- Lancement de l'interpreteur -----
ERREUR: ] manquant !
---- Fin du programme -----


Voici un code-source inconnu, à vous de trouver ce qu'il fait.
>++++++++++>+>+[
    [+++++[>++++++++<-]>.<++++++[>--------<-]+<<<]>.>>[
        [-]<[>+<-]>>[<<+>+>-]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-
            [>+<-[>+<-[>+<-[>[-]>+>+<<<-[>+<-]]]]]]]]]]]+>>>
    ]<<<
]


Bonus : Créer un interpréteur pour le langage C. :p (humour)

Si vous avez des questions, n'hésitez-pas à les poser.

-------------------------------------------------------------------------------------------------

Vous avez jusqu'au 15 août pour soumettre vos réponses à Réponse_Exercices.

Bonne chance à tous !
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
15 juillet 2008 à 22:31:53

Je vais le faire celui-là, mais si tu pouvais nous faire un exemple expliqué de '[' et ']' car j'ai un peu de mal à comprendre ce qu'ils font, merci.
15 juillet 2008 à 23:00:11

'[' et ']' correspondent à un do { /*...*/ } while(/*case pointée différente de 0*/);
15 juillet 2008 à 23:01:59

En fait, [ et ] délimitent une boucle. Dès que le programme arrive sur le ], il vérifie la valeur de la case du tableau pointée : si elle est égale à 0, le programme continue son exécution, sinon il reprend à partir du [ correspondant.

Edit : @Nanoc : euh le 2ème programme tu l'as écrit au hasard ? :s Car chez moi il affiche pleins de caractères qui ne veulent rien dire et fais des beep (sûrement le caractère beep ^^ ).
Peut-être qu'il y a un bug dans mon programme ?
16 juillet 2008 à 1:10:08

C'est pas trop do{/*...*/}while(*ptr != 0); mais plutôt while(*ptr != 0){/*...*/}
Mais sinon l'exercice là c'est plus trop du C++, c'est du C, à la limite on pourrais faire un tableau de vector pour que ça fasse du C++ ?
C'est autorisé ?
16 juillet 2008 à 1:31:19

Moi j'y suis arrivé en C...
Mais en fait le plus simple aurait été de convertir un fichier BF en fichier C...
16 juillet 2008 à 8:48:45

@Chlab_lak : Quand tu rencontre un [, tu vérifies la valeur de l'octet pointé. Si c'est pas 0, tu continues comme si il ne s'était rien passé. Si c'est 0, tu sautes à l'instruction qui suit le ] correspondant. C'est-à-dire qui va à la parenthèse fermante qui est liée à la parenthèse ouvrante.
Pour le ], c'est la même chose en inversant les valeurs.

@Hunlyxod et Eclyps: Ce n'est ni l'un ni l'autre, c'est les deux à la fois. C'est symétrique (les deux [] font la même chose) ce qui n'est pas le cas en C/C++

@Nono212: Non,non, il est correct. Convertir le fichier BF en C, c'est trop facile. Le but est de l'interpréter correctement et de trouver les erreurs, si il y en a.

@Eclyps: Pourquoi du C ? On pourrait le faire en nimporte quel langage (même en BF :) ). Ce code en "vrai" C++ utilise les flux standards, les conteneurs standards, les itérateurs, les exceptions, les string , etc. C'est pas parce qu'il n'y a pas de classe à écrire que c'est du C. Je te défie de gérer correctement les erreurs en C.
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
16 juillet 2008 à 13:18:53

Eh bien c'est un langage de niveau tellement bas que utiliser le C++ pourrait emcombrer... (surtout pour le traitement : les strings seraient inutiles dans ce cas là, mieux vaut le simple char *, qui a l'avantage d'être un pointeur et d'être simple à utiliser...).
Anonyme
16 juillet 2008 à 13:26:50

tu trouves les std::string compliquées o_O ?
16 juillet 2008 à 13:39:01

Pour ce genre d'utilisation trop complexe...
16 juillet 2008 à 14:08:46

Ce n'est pas un argument très pertinent. Les string sont tout ausi efficaces que les char* (et même plus), plus sécurisées et on a pas besoinde gérer sois-même la mémoire. Faut être maso pour ne pas les utiliser.
Si tu bossais sur un ordi avec pas assez de RAM, alors oui, mais ça fait au moins 20 ans que ce genre de soucis n'ont plus lieu d'être.

P.S.: 500ème post.
Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
16 juillet 2008 à 14:29:02

Bah justement, dans ce programme on doit gérer soi-même la mémoire ^^ (en tout cas ça permet un utilisation plus pratique, exemple on a notre programme contenu dans une variable char *var, on a juste à faire var++ pour passer à l'instruction suivante...)
16 juillet 2008 à 15:12:35

Et ?
1- en quoi ce n'est pas possible avec les std::string?
2- cela n'économise pas le besoin de gérer la mémoire à la main.
C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
Anonyme
16 juillet 2008 à 15:25:21

Citation : nono212

une variable char *var, on a juste à faire var++ pour passer à l'instruction suivante...)

itérateur?
16 juillet 2008 à 16:20:44

En fait je me suis jamais renseigné sur les trucs style itérateurs, etc. (tout ce qui concerne la librairie standard est pas trop mon truc).
Si on peut avec, alors c'est super (il faut vraiment que je me renseigne...)
16 juillet 2008 à 16:35:36

Ouf fini les statistiques des fichiers :
╔═════════════════════════════════╦═════╗
║Nombre de caractère              ║ 499 ║
║Nombre de caractère sans espace  ║ 66  ║
║Nombre de mots                   ║ 52  ║
║Nombre de paragraphe             ║ 2   ║
╚═════════════════════════════════╩═════╝


J'ai un peu modifier la forme du tableaux :p

Je suis a ces statistique pour :
A                       Z
 B                     Y
  C                   X
   D                 W
    E               V
     F             U
      G           T
       H         S
        I       Q
         J     P
          K   O
           L N
            M
           L N
          K   O
         J     P
        I       Q
       H         S
      G           T
     F             U
    E               V
   D                 W
  C                   X
 B                     Y
A                       Z

Voili Voilà
Eclyps
16 juillet 2008 à 16:47:17

Sont bizarre tes stats.
y a que 30 espaces dans ton texte ? T'en a déjà 23 entre le A et le Z.
39 mots ? Tu as déjà 25+24 lettres seul, plus les 3 de la fin, ca fait 52 mots.
4 paragraphes ? Sont où ?

PS: tu as oublié le R
16 juillet 2008 à 18:06:39

Merde pendant que je poster le message j'ai voulu mettre un autre texte puis j'ai changé mais j'ai oublier de conger le tableau de la console.
Je modifie...
C'est bon fini ^^
16 juillet 2008 à 21:27:58

Citation : Nanoc

@Chlab_lak : Quand tu rencontre un [, tu vérifies la valeur de l'octet pointé. Si c'est pas 0, tu continues comme si il ne s'était rien passé. Si c'est 0, tu sautes à l'instruction qui suit le ] correspondant. C'est-à-dire qui va à la parenthèse fermante qui est liée à la parenthèse ouvrante.
Pour le ], c'est la même chose en inversant les valeurs.



Merci, j'ai compris, mais j'ai encore des questions:
- Apparamment les octects sont des caractères, donc on peut afficher un warning si le code source tente de faire passer la valeur d'un octet en négatif ?
- De même on peut afficher un warning si le code source tente d'accéder à l'octet -1 ?
- Quand je parle de warning, je pense que l'interpreteur ignore la commande, on peut faire comme ça ?

Merci d'avance, je posterais si j'ai d'autres questions.