Org Mode Babel - Valutazione interattiva del blocco di codice


12

Vorrei valutare in blocchi di codice sorgente in modalità org in C ++ contenenti istruzioni "cin" ma non riesco a trovare un modo per avere una valutazione interattiva (con input dell'utente) durante la valutazione. Esempio di codice:

#+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

È possibile avere una valutazione così interattiva o simulare (dando al codice sorgente un input falso)?


Hai davvero bisogno che sia interattivo o devi solo dargli qualche input che potresti già conoscere in anticipo, ma non in questo blocco di codice? Il secondo caso è più semplice: è possibile utilizzarlo :var varname=valuenell'intestazione. Nel secondo caso è ancora possibile utilizzare :var, ma al posto del valore utilizzare un altro blocco di codice con una funzione ELisp che richiede input.
wvxvw,

Grazie @wvxvw per la tua risposta; Quello che voglio fare è fare un documento con alcuni esempi di programmi per studenti e quindi vorrei mantenere il blocco del codice sorgente "così com'è"; quindi la mia preferenza sarebbe il secondo caso che menzionate; Proverò a seguire il tuo suggerimento (per usare: var e un codice elisp per chiedere input), hai un link o un esempio di tale chiamata?
Lgen,

Oh, scusa, c'è stato un po 'di incomprensioni. Il secondo esempio userebbe Emacs per leggere l'input, ma Babel non chiamerà il programma C ++ in modo tale da consentire l'interazione. L'unica cosa a cui posso pensare è che se aggiungi una funzione "polimorfica" al tuo codice, che ha due implementazioni: una, dove leggi l'input in modo interattivo, e un'altra, dove lo leggi da un file o fornisci durante la valutazione del blocco di codice .
wvxvw,

Risposte:


8

Come questo:

#+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

Creare un file in.txtnella stessa directory del file Org, con i contenuti 10.


7

Puoi chiedere a Emacs di ottenere l'input interattivo invece utilizzando un elispblocco denominato . Quindi passare il valore raccolto al blocco souce C ++ utilizzando la :var c-variable=block-namesintassi:

#+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 

Nota che le uscite dei blocchi sorgente vengono passate come stringhe, quindi dobbiamo convertirle in un numero intero, da qui il atoie l'extra #include.


1
Fai come vuoi. Tuttavia, il tuo codice è legato alla modalità Org, mentre il mio può essere incollato alla lettera e compilato prontamente.
abo-ABO

1
Grazie @erikstrokes per questo contributo; Ho avuto un'idea simile (usare un blocco esterno) e ho fatto un mix con la soluzione abo-abo. Ho pubblicato il risultato come risposta.
Lgen,

4

Grazie @ abo-abo per il tuo aiuto. Ho seguito il tuo suggerimento che è giusto e l'ho persino migliorato un po 'per modificare solo il mio file org (e per creare automaticamente il file di input esterno). L'idea è quella di creare un blocco di codice esterno (qui uno script bash chiamato build_input_file) che crea il file di dati e di chiamarlo automaticamente prima di valutare l'altro blocco grazie al :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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.