Console (Invité de commande) en C
Résolu/Fermé
A voir également:
- Console (Invité de commande) en C
- Invite de commande - Guide
- Commande terminal mac - Guide
- Commande en attente d'acceptation fnac ✓ - Forum Consommation & Internet
- Retrouver clé windows 10 invite de commande - Guide
- Alexia organise un séminaire en ligne (webinaire) : elle cherche un outil qui permet de gérer les invitations, de relancer les invités et d’enregistrer le webinaire. - Forum Word
5 réponses
Hxyp
Messages postés
401
Date d'inscription
vendredi 28 janvier 2011
Statut
Membre
Dernière intervention
27 avril 2014
54
Modifié par Hxyp le 4/01/2012 à 17:31
Modifié par Hxyp le 4/01/2012 à 17:31
Bonjour,
il faut définir et décomposer vôtre syntaxe pour ensuite analyser les éléments,
en reprenant l'exemple donné :
aff.texte("Letexte");
on pourrait dire que le . sépare la commande d'une fonction et que la parenthèse ( sépare la fonction de son "corps"
avant le point = commande
entre le point et la parenthèse = fonction
le reste = corps
à partir de là on peut analyser et relier les éléments etc...
bout de code pour l'explication :
en dehors de l'exemple donné j'ai ajouté la fonction "plop" pour montrer que le principe est relativement simple/souple/modifiable? bref ça devrait vous donner quelques idées
[Edit] je n'ai pas traité les guillemets ni la fin d'instruction par le point-virgule seulement utilisé les parenthèses donc ils ne sont pas utilisaient pour ce code,
aff.texte(hello\nworld)
aff.plop(50)
il faut définir et décomposer vôtre syntaxe pour ensuite analyser les éléments,
en reprenant l'exemple donné :
aff.texte("Letexte");
on pourrait dire que le . sépare la commande d'une fonction et que la parenthèse ( sépare la fonction de son "corps"
avant le point = commande
entre le point et la parenthèse = fonction
le reste = corps
à partir de là on peut analyser et relier les éléments etc...
bout de code pour l'explication :
#include <stdio.h> #include <string.h> #include <stdlib.h> #define NBCF 3 /* nombre de cmd&fonc dans la struct */ void aff(char*); void texte(char*); void plop(char*); struct fonc{ char *nom;/* nom de la fonction ou commande */ void (*ptr)(char*);/* son address */ }ff[NBCF]={ {"aff",aff}, {"texte",texte}, {"plop",plop}}; void aff(char *fonc){ char *corps; int i; for(i=0;fonc[i]!='(';i++);/* stop si on tombe sur ( */ fonc[i]='\0';/* remplace la ( par un 0 sépare la fonc de son "corps" */ corps=&fonc[i+1];/* apres la ( c'est le corps de la fonc */ for(i=0;i<NBCF;i++) if(!strcmp(ff[i].nom,fonc)){ ff[i].ptr(corps);/* envoie le corps dans la fonc */ } } void texte(char *txt){ int i,j=0; for(i=0;txt[i];i++){ if(txt[i]!=')'){ if(txt[i]=='\\'){/* si backslash */ switch(txt[i+1]){ case 'n': txt[i]='\n'; ++j; break; case 'r': txt[i]='\r'; ++j; break; case 't': txt[i]='\t'; ++j; break; case '\\': txt[i]='\\'; ++j; break; default:break; } } if(j){ putc(txt[i],stdout); i++; j=0; } else { putc(txt[i],stdout); } } else break; } } void plop(char *a){ int i,x; for(i=0;a[i]!=')';i++); a[i]=0; x=atoi(a); printf("plop --> %d\n",x); } void interp(char *s) { char *cmd,*fonc; int i; for(i=0;s[i]!='.';i++);/* stop si on tombe sur le . */ s[i]='\0';/* remplace le . par un 0 ça coupe la chaine en deux */ cmd=s;/* avant le . c'est la commande */ fonc=&s[i+1];/* apres le . c'est la fonction */ for(i=0;i<NBCF;i++)/* boucle sur la struct des cmd et fonc */ if(!strcmp(ff[i].nom,cmd))/* cherche la commande */ ff[i].ptr(fonc);/* envoie la fonc dans la cmd */ } int main(int argc,char *argv[]) { char *tmp; tmp=malloc(sizeof(char)*strlen(argv[1])+1);/* alloue la mémoire */ strcpy(tmp,argv[1]);/* met la chaine dans tmp */ interp(tmp);/* envoie tmp pour interpretation */ free(tmp); return 0; }
en dehors de l'exemple donné j'ai ajouté la fonction "plop" pour montrer que le principe est relativement simple/souple/modifiable? bref ça devrait vous donner quelques idées
[Edit] je n'ai pas traité les guillemets ni la fin d'instruction par le point-virgule seulement utilisé les parenthèses donc ils ne sont pas utilisaient pour ce code,
aff.texte(hello\nworld)
aff.plop(50)
Hxyp
Messages postés
401
Date d'inscription
vendredi 28 janvier 2011
Statut
Membre
Dernière intervention
27 avril 2014
54
4 janv. 2012 à 22:02
4 janv. 2012 à 22:02
De quel façon le scanf sera utilisé ?
Si c'est dans une fonction ça ne change pas, par exemple en modifiant la fonction plop :
puis "plop." ou "aff.plop()" vu que la différence n'est pas faite entre les "cmd" et "fonc" (avec le .)
Si vous parlez d'un scanf pour récupérer les instructions dans le main et les executer sans que le programme ne se ferme :
Si c'est dans une fonction ça ne change pas, par exemple en modifiant la fonction plop :
void plop(char *a){ int x; printf("entrez un nombre : "); scanf("%d",&x); printf("resultat : %d\n",x*x); }
puis "plop." ou "aff.plop()" vu que la différence n'est pas faite entre les "cmd" et "fonc" (avec le .)
Si vous parlez d'un scanf pour récupérer les instructions dans le main et les executer sans que le programme ne se ferme :
int main(void) { char tmp[256];/* limite la taille de chaque instruction à cause de scanf */ while(1){/* boucle infini */ scanf("%255s",tmp); interp(tmp); } return 0; }
Utilisateur anonyme
4 janv. 2012 à 18:47
4 janv. 2012 à 18:47
Je ne sais pas comment te remercier :D juste une dernière question, quand je vais faire un scanf, faut t'il qu'il pointe vers quelque chose ou pas ?
Merci encore
Merci encore
Utilisateur anonyme
4 janv. 2012 à 22:11
4 janv. 2012 à 22:11
Merci je vient de comprendre enfin :) J'ai d'autres questions, comme je pense que recréer un sujet identique à celui là serait bête, je vais les poser ici.. :
La fonction afficher vient d'être créer, mais est-ce que je peut faire phrase plus grande ou pas, car faire un retour à la ligne à chaque fois est chiant.
Pour assigner d'autre commande, comment dois-je m'y prendre ?
Encore merci une nouvelle fois :)
La fonction afficher vient d'être créer, mais est-ce que je peut faire phrase plus grande ou pas, car faire un retour à la ligne à chaque fois est chiant.
Pour assigner d'autre commande, comment dois-je m'y prendre ?
Encore merci une nouvelle fois :)
Hxyp
Messages postés
401
Date d'inscription
vendredi 28 janvier 2011
Statut
Membre
Dernière intervention
27 avril 2014
54
5 janv. 2012 à 01:51
5 janv. 2012 à 01:51
Normalement il n'y a pas de limite de taille par instruction à part dans la modification avec le scanf que j'ai donné (la modification du main) j'ai limité la taille du buffer à 256char et mis la limitation à 255 dans le scanf pour pas que ça dépasse la taille du buffer mais vous pouvez mettre un buffer à la taille que vous désirez et donc pouvoir faire des instructions plus grandes et afficher des phrases plus grandes du coup.
Il faut aussi un retour à la ligne à chaque instruction, en ajoutant un symbole de fin comme le point-virgule ça résoudrait le problème. Petite modification s'impose pour ça :
maintenant vous pouvez utiliser plusieurs instructions dans une seule ligne en les terminant par un point-virgule ;
exemple :
aff.texte(hello\n);aff.texte(world\n);
mes bouts de code sont à titre d'exemples et comme vous avez pu le constatez il n'y a pas de vérifications des erreurs de syntaxe et donc si elle n'est pas respectée le programme plantera.
Pour ajouter une commande suffit d'ajouter 1 dans le define NBCF c'est le compteur et d'ajouter dans le tableau de la structure ( ff[NBCF] ) le nom de la commande qui sera utiliser dans l'instruction (entre les guillemets) et le nom de sa fonction (celle en C) et c'est tout. Ne pas oublier de mettre un pointeur char* en paramètre de la nouvelle fonction qui servira pour la commande car la structure est fait de sorte que "interp" puisse envoyer ce qui suit le point (.) d'une instruction en paramètre d'une nouvelle fonction.
exemple si on veut ajouter une commande qui affiche "hello" :
on met nbcf à 4 (car la structure contient maintenant aff,texte,plop + hello)
#define NBCF 4
on ajoute le prototype de nôtre nouvelle fonction car on utilise pas de header et qu'il faut respecter l'ordre :
void hello(char*);
dans le tableau de la struct on ajoute la commande et le nom de sa fonction c :
puis pour terminer (quoique c'est par là que je commencerai ahahah) on ajoute la fonction qui affiche "hello" :
char *a n'est pas utilisé mais il faut le mettre quand même car dans la struct qui prend l'adresse c'est utile aux autres fonctions qui récupère les données envoyé par "interp". là pour afficher "hello" ce sera l'instruction salut.; si vous faites salut.test; la fonction hello va recevoir "test" dans a
Il faut aussi un retour à la ligne à chaque instruction, en ajoutant un symbole de fin comme le point-virgule ça résoudrait le problème. Petite modification s'impose pour ça :
char *sget(size_t max,char *s){ char c;size_t i; for(i=0;(c=getchar())!='\n'&&i<max-1;i++) s[i]=c; return s; } int main(void) { int i; char *tmp,*a; tmp=malloc(sizeof(char)*0xFFFF);/* alloue 65ko */ while(1){ memset(tmp,0,sizeof(char)*0xFFFF); tmp=sget(0xFFFF,tmp); a=tmp; for(i=0;tmp[i];i++) if(tmp[i]==';'){ tmp[i]=0; interp(a); a=&tmp[i+1]; i++; } } free(tmp); return 0; }
maintenant vous pouvez utiliser plusieurs instructions dans une seule ligne en les terminant par un point-virgule ;
exemple :
aff.texte(hello\n);aff.texte(world\n);
mes bouts de code sont à titre d'exemples et comme vous avez pu le constatez il n'y a pas de vérifications des erreurs de syntaxe et donc si elle n'est pas respectée le programme plantera.
Pour ajouter une commande suffit d'ajouter 1 dans le define NBCF c'est le compteur et d'ajouter dans le tableau de la structure ( ff[NBCF] ) le nom de la commande qui sera utiliser dans l'instruction (entre les guillemets) et le nom de sa fonction (celle en C) et c'est tout. Ne pas oublier de mettre un pointeur char* en paramètre de la nouvelle fonction qui servira pour la commande car la structure est fait de sorte que "interp" puisse envoyer ce qui suit le point (.) d'une instruction en paramètre d'une nouvelle fonction.
exemple si on veut ajouter une commande qui affiche "hello" :
on met nbcf à 4 (car la structure contient maintenant aff,texte,plop + hello)
#define NBCF 4
on ajoute le prototype de nôtre nouvelle fonction car on utilise pas de header et qu'il faut respecter l'ordre :
void hello(char*);
dans le tableau de la struct on ajoute la commande et le nom de sa fonction c :
struct fonc{ char *nom; void (*ptr)(char*); }ff[NBCF]={ {"aff",aff}, {"texte",texte}, {"plop",plop}, {"salut",hello}, /* ici */ };
puis pour terminer (quoique c'est par là que je commencerai ahahah) on ajoute la fonction qui affiche "hello" :
void hello(char *a){ printf("hello\n"); }
char *a n'est pas utilisé mais il faut le mettre quand même car dans la struct qui prend l'adresse c'est utile aux autres fonctions qui récupère les données envoyé par "interp". là pour afficher "hello" ce sera l'instruction salut.; si vous faites salut.test; la fonction hello va recevoir "test" dans a
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Utilisateur anonyme
5 janv. 2012 à 20:32
5 janv. 2012 à 20:32
Merci de ton aide, j'aimerais savoir si c'était possible de créer le même type de fonction vers d'autres types de langages, de genre Java ?
Hxyp
Messages postés
401
Date d'inscription
vendredi 28 janvier 2011
Statut
Membre
Dernière intervention
27 avril 2014
54
6 janv. 2012 à 02:53
6 janv. 2012 à 02:53
Oui normalement il ne devrait pas y avoir de problème à porter cette "méthode" dans d'autre langage, mais ne m'intéressant pas au java je ne pourrai pas vous y aider
ps: dans ma réponse précédente j'ai écris
"tmp=malloc(sizeof(char)*0xFFFF);/* alloue 65ko */"
ne pouvant pas éditer mon post pour corriger... ce n'est pas 65ko qui sont alloués mais 64ko...
ps: dans ma réponse précédente j'ai écris
"tmp=malloc(sizeof(char)*0xFFFF);/* alloue 65ko */"
ne pouvant pas éditer mon post pour corriger... ce n'est pas 65ko qui sont alloués mais 64ko...