Org Mode Babel - Évaluation interactive des blocs de code

12

Je voudrais évaluer en mode org des blocs de code source en C ++ contenant des instructions "cin" mais je ne trouve pas un moyen d'avoir une évaluation interactive (avec une entrée utilisateur) pendant l'évaluation. Exemple de code:

#+BEGIN_SRC C++  :results output :export code :tangle myfile.cpp 
#include <iostream>
using namespace std;

int main()
{
int a;
cin>>a;
cout<<a+1;
}
#+END_SRC

Est-il possible d'avoir une telle évaluation interactive ou de simuler (en donnant au code source une fausse entrée)?

Lgen
la source
En avez-vous réellement besoin pour qu'il soit interactif, ou avez-vous simplement besoin de lui donner une entrée que vous connaissez peut-être déjà à l'avance, mais pas dans ce bloc de code? Le deuxième cas est plus simple: vous pouvez utiliser :var varname=valuedans l'en-tête. Dans le second cas, vous pouvez toujours utiliser :var, mais à la place de la valeur, utilisez un autre bloc de code avec une fonction ELisp qui demande une entrée.
wvxvw
Merci @wvxvw pour votre réponse; Ce que je veux faire est de faire un document avec des exemples de programme pour les étudiants et donc je voudrais garder le bloc de code source "tel quel"; donc ma préférence serait le deuxième cas que vous mentionnez; Je vais essayer de suivre votre suggestion (utiliser: var et un code elisp pour demander une entrée), avez-vous un lien ou un exemple d'un tel appel?
Lgen
Oh, désolé, il y a eu un petit malentendu. Le deuxième exemple utiliserait Emacs pour lire l'entrée, mais Babel n'appellera pas le programme C ++ de manière à permettre l'interaction. La seule chose à laquelle je peux penser est que si vous ajoutez une fonction "polymorphe" à votre code, qui a deux implémentations: une, où vous lisez l'entrée de manière interactive, et une autre, où vous la lisez à partir d'un fichier ou fournissez pendant l'évaluation du bloc de code .
wvxvw

Réponses:

8

Comme ça:

#+begin_src C++ :results output :cmdline < in.txt
#include <iostream>
int main(int argc, char *argv[]) {
  int a;
  std::cin >> a;
  std::cout << a + 1;
  return 0;
}

#+end_src

#+RESULTS:
: 11

Créez un fichier in.txtdans le même répertoire que le fichier Org, avec son contenu 10.

abo-abo
la source
7

Vous pouvez demander à Emacs d'obtenir l'entrée interactive à la place en utilisant un elispbloc nommé . Passez ensuite la valeur collectée au bloc souce C ++ en utilisant la :var c-variable=block-namesyntaxe:

#+name: input_block
#+BEGIN_SRC elisp :export none :results none
(completing-read "a=" nil)

#+END_SRC

#+BEGIN_SRC C++  :results output :export code :tangle myfile.cpp :var input=input_block
  #include <stdlib.h>
  #include <iostream>
  using namespace std;

  int main()
  {
  int a = atoi(input);
  cout<<a+1;
  }
#+END_SRC 

Notez que les sorties des blocs source sont transmises sous forme de chaînes, nous devons donc le convertir en un entier, d'où le atoiet le supplément #include.

erikstokes
la source
1
Fais comme tu veux. Cependant, votre code est lié au mode Org, tandis que le mien peut être copié textuellement et facilement compilé.
abo-abo
1
Merci @erikstrokes pour cette contribution; J'ai eu une idée similaire (utiliser un bloc externe) et j'ai fait un mix avec une solution abo-abo. J'ai posté le résultat comme réponse.
Lgen
4

Merci @ abo-abo pour votre aide. J'ai suivi votre suggestion qui est juste et je l'ai même un peu améliorée pour modifier uniquement mon fichier org (et pour créer automatiquement le fichier d'entrée externe). L'idée est de créer un bloc de code externe (ici un script bash nommé build_input_file) qui crée le fichier de données et de l'appeler automatiquement avant d'évaluer l'autre bloc grâce au :var tmp=build_input_file.

#+name: build_input_file
#+BEGIN_SRC bash  :results none :exports none 
echo "10 12" > in.txt
#+END_SRC

#+name: my_function_with_cin
#+BEGIN_SRC C++  :results output :exports both  :var tmp=build_input_file :cmdline < in.txt
#include <iostream>
using namespace std;

int main()
{
 int a,b;
 cin>>a>>b;
 cout<<a<<" "<<b;
}
#+END_SRC
Lgen
la source