Console (Invité de commande) en C

Résolu/Fermé
Utilisateur anonyme - 3 janv. 2012 à 19:17
 Utilisateur anonyme - 6 janv. 2012 à 15:28
Bonjour,

J'aimerais créer une console en C chose que vous aller dire assez facile de faire..
Mais mon problème c'est qu'à la base j'ai réaliser un "style d'OS" via windows afin d'ouvrir internet seulement par des raccourcis claviers.
je trouve ces raccourcis claviers compliqué et j'ai décidé de créer mon propre système, qui interprétera si on peut aller par là, mon propre langage interprété.

Exemple console :

aff.texte("Letexte");

serais l'équivalent de faire ça :

printf("Letexte");

Comment dire, en faisant une condition, si l'utilisateur entre "ceci" alors exécuté la commande "cela".
J'ai fait un scanf mais je sais pas si c'est la meilleur des solutions.

Pouvez vous m'aider ?



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
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 :

#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)
1
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
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 :
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;
  }
1
Utilisateur anonyme
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
0
Utilisateur anonyme
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 :)
0
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
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 :
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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Utilisateur anonyme
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 ?
0
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
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...
0
Utilisateur anonyme
6 janv. 2012 à 15:28
Je vient de voir quelque petits tutos sur le java, mes notions en C sont faible donc je vais m'améliorer un peu plus.. Merci beaucoup !! :)
0