Call une fonction avec un string

Bonjour,

Je suis sur un projet et il me reste plus que cette étape pour finir, ce que je souhaite :

Ma fonction à exécuté.

void test();
{
.....
}

Mon String qui contient ma fonction

String test2 = "test();"

Appelle de la fonction

test;

Cependant je sais que ce n'est pas possible mais je n'ai pas de solutions, il faut savoir que je ne connais pas mes fonctions à l'avance ( elles sont rentré par l'utilisateur )

La méthode :

void (*myFunctions[])(void)={test};

Pourrais fonctionner si je rentrerais la fonction en dur dans le code, or ici c'est l'utilisateur qui va rentrer la fonction à exécuté, je ne peux pas convertir un String en void ( du moins à ma connaissance )

Merci pour une solution proposé !

Cordialement,

Il n'y a pas de solution au sens où tu l'entends. Tu dois comparer le nom de fonction entré par l'utilisateur à ceux que tu as dans ton code, et appeler celle qui convient.

Pour le faire, ça dépend du type de variable que tu utilises pour lire ce qui est entré dans la console :

  • String : == doit faire l'affaire
  • Tableau de char : strcmp

En pseudo code, tu crées un tableau avec les noms de tes fonctions

  • Acquérir l'entrée de l'utilisateur
  • Pour i variant de 0 au nombre de fonctions
  • Comparer le nom entré par l'utilisateur au nom de fonction indicé 'i'
  • Si égalité, appeler la fonction
  • Sinon, continuer la boucle
    Il est possible de créer un tableau de fonctions et d'exécuter la fonction numéro 'i' de ce tableau. Voir le code ici. Il faut que toutes les fonctions aient le même nombre d'arguments.

Merci de ta réponse !

Il n'existe donc aucune méthode d'appel de fonction par l'écriture d'un utilisateur ?
Je suis obligé de les mettres dans tableau ? :frowning:

C'est ce que je crois, sauf nouveauté dans le langage C

D'accord je pars sur ça merci de ta réponse !

Bonne journée

Avec PYTHON c'est tout à fait possible, mais pas en C.

Salut ,

quand on appelle une fonction dans son code , il faut faire

test();

et pas test ; comme dans votre premier post .

par la suite vous pouvez tres bien testé si l ' utilisateur a entré des données , tester si elles sont celles attendues , puis lancez une fonction .
c ' est transparent pour l' utilisateur .

En effet Iznobe c'est un oublie

lesept:

  • Pour i variant de 0 au nombre de fonctions
  • Comparer le nom entré par l'utilisateur au nom de fonction indicé 'i'
  • Si égalité, appeler la fonction
  • Sinon, continuer la boucle

Je n'arrive pas à comparé un String, Char à l'indice i de ma fonction sachant que ma fonction est : void (*myFunctions[])(void)={test};

A tu un exemple à me donner s'il te plaît ?

Merci.

Bonjour,

Il suffit de comparer la chaîne reçue avec une chaîne qui contient le nom de la fonction.

  String strFonction;

  // Réception du nom de la fonction
  // ...
  if (strFonction=="test1")
    test1();
  else if (strFonction=="test2")
    test2();
  else if (strFonction=="test3")
    test3();
  else if (strFonction=="test4")
    test4();
  // ...

Remarque: il est conseillé de ne pas utiliser les String mais plutôt d'utiliser les c_string (tableau de char) avec strcmp.
Je ne vois pas très bien l'utilité d'appeler une fonction par son nom.

un truc approchant , fais a la va vite :

enum : uint8_t {fonction1, fonction2, fonction3, fonction4, fonction5};
const char* tableauDeFonctions [ fonction5 ] = {"fonction1()", "fonction2()", "fonction3()", "fonction4()", "fonction5()"};

if ( donneUtilisateurEntre ) { // controle que  l ' utilisateur a entre un truc
	for ( byte i = 0; i < fonction5; i++ ) { // boucle 
		if ( donneUtilisateurEntre == i ) { //comparaison des données utilisateurs avec un enum du nom des fonctions 
			Serial.print(tableauDeFonctions [ i ])
			}	
		}
	
	}
}

Bonjour Iznobe merci de ton aide.

enum : uint8_t {fonction1, fonction2, fonction3};
const char* tableauDeFonctions [fonction3] = {"fonction1()", "fonction2()", "fonction3()"};

void loop() {
 tableauDeFonctions[0];
}

void fonction1(){
  Serial.println("test1");  
}

void fonction2(){
  Serial.println("test2");  
}

void fonction3(){
  Serial.println("test3");  
}

Cependant je voulais testé si le code permet de call une fonction mais apparemment non je ne comprend pas trop pourquoi ?

L'erreur dans l'IDE arduino :

Arduino : 1.8.12 (Windows 10), Carte : "Arduino Due (Programming Port)"

fonc:5:17: error: 'fonction1' redeclared as different kind of symbol

 enum : uint8_t {fonction1, fonction2, fonction3};

                 ^

fonc:12:6: error: previous declaration of 'void fonction1()'

 void fonction1(){

      ^

fonc:5:28: error: 'fonction2' redeclared as different kind of symbol

 enum : uint8_t {fonction1, fonction2, fonction3};

                            ^

fonc:16:6: error: previous declaration of 'void fonction2()'

 void fonction2(){

      ^

fonc:5:39: error: 'fonction3' redeclared as different kind of symbol

 enum : uint8_t {fonction1, fonction2, fonction3};

                                       ^

fonc:20:6: error: previous declaration of 'void fonction3()'

 void fonction3(){

      ^

fonc:6:42: error: size of array 'tableauDeFonctions' has non-integral type 'void()'

 const char* tableauDeFonctions [fonction3] = {"fonction1()", "fonction2()", "fonction3()"};

                                          ^

fonc:6:90: error: too many initializers for 'const char* [1]'

 const char* tableauDeFonctions [fonction3] = {"fonction1()", "fonction2()", "fonction3()"};

le tableau et le enum etait donné en exemple il ne faut pas mettre les 2 , meme si j' ai fais un mix dans le code d' exemple que j' ai tapé en catastrophe diretement ici , sans verifier avec l ' IDE.

voici une debut de piste qui est valide dans l' IDE , avec un tableau qui pourrait etre utilisé , reste ensuite a a adapter avec ton code .

char donneUtilisateurEntre;
const char* tableauDeFonctions [ 5 ] = {"fonction1()", "fonction2()", "fonction3()", "fonction4()", "fonction5()"};
void testEntreeUtilisateur () {
    
    if ( donneUtilisateurEntre ) { // controle que  l ' utilisateur a entre un truc
        for ( byte i = 0; i < 5; i++ ) { // boucle
            if ( donneUtilisateurEntre == i ) { //comparaison des données utilisateurs avec un enum du nom des fonctions
                Serial.print(tableauDeFonctions [ i ]); 
            }
       }
    }
}

Le code marche parfaitement, néanmoins on ne peux pas exécuter la fonction écrite dans le tableau, il permet bien de récupéré et de faire une comparaison, le soucis étant que je souhaite aussi après cette manœuvre que la fonction sois exécute, c'est pour cela que j'avais au départ utilisé

void (*myFunctions[])(void) = {fonction1, fonction2};

ba , il suffit de remplacer le serial print dans mon exemple , par l' appel a la fonction correspondante .

avec le if else que t ' a donné kamill dans sa reponse precedente ...

comme cela :

//enum : uint8_t {fonction1, fonction2, fonction3, fonction4, fonction5};
char donneUtilisateurEntre;
const char* tableauDeFonctions [ 5 ] = {"fonction1()", "fonction2()", "fonction3()", "fonction4()", "fonction5()"};
void fonction1 () {
    Serial.println("fonction 1 executée");
}
void fonction2 () {
    Serial.println("fonction 2 executée");
}
void testEntreeUtilisateur () {
    
    if ( donneUtilisateurEntre ) { // controle que  l ' utilisateur a entre un truc
        for ( byte i = 0; i < 5; i++ ) { // boucle
            if ( donneUtilisateurEntre == i ) { //comparaison des données utilisateurs avec un enum du nom des fonctions
                Serial.print(tableauDeFonctions [ i ]);
                
                if ( tableauDeFonctions [ i ]  == "fonction1" ) fonction1();
                else if (tableauDeFonctions [ i ] == "fonction2" ) fonction2();
                /// etc
            }
       }
    }
}

void setup() {
    Serial.begin(115200);
    // put your setup code here, to run once:

}

void loop() {
    // put your main code here, to run repeatedly:

}

Ah, je n'ai pas vu sont post... Autant pour moi ! De cette façons sa fonctionnerais oui, merci :wink: