Org Mode Babel - Interaktive Codeblockauswertung

12

Ich möchte im org-Modus Quellcodeblöcke in C ++ auswerten, die "cin" -Anweisungen enthalten, aber ich kann keine Möglichkeit finden, während der Auswertung eine interaktive Auswertung (mit Benutzereingaben) durchzuführen. Beispiel für 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

Ist es möglich, eine solche interaktive Auswertung durchzuführen oder zu simulieren (indem dem Quellcode eine gefälschte Eingabe gegeben wird)?

Lgen
quelle
Benötigen Sie es tatsächlich, um interaktiv zu sein, oder müssen Sie ihm nur einige Eingaben geben, die Sie möglicherweise bereits im Voraus kennen, nur nicht in diesem Codeblock? Der zweite Fall ist einfacher: Sie könnten :var varname=valuein der Kopfzeile verwenden. Im zweiten Fall könnten Sie noch einen :varanderen Codeblock mit einer ELisp-Funktion verwenden, der zur Eingabe auffordert.
wvxvw
Vielen Dank an @wvxvw für Ihre Antwort. Was ich tun möchte, ist, ein Dokument mit einigen Programmbeispielen für Studenten zu erstellen, und deshalb möchte ich den Quellcodeblock "wie er ist" behalten; Meine Präferenz wäre also der zweite Fall, den Sie erwähnen. Ich werde versuchen, Ihrem Vorschlag zu folgen (um: var und einen Elisp-Code zu verwenden, um nach Eingaben zu fragen). Haben Sie einen Link oder ein Beispiel für einen solchen Aufruf?
Lgen
Oh, sorry, es gab ein bisschen Missverständnisse. Im zweiten Beispiel würde Emacs zum Lesen der Eingabe verwendet, aber Babel ruft das C ++ - Programm nicht so auf, dass eine Interaktion möglich ist. Das einzige, woran ich denken kann, ist, dass Sie Ihrem Code eine "polymorphe" Funktion hinzufügen, die zwei Implementierungen aufweist: eine, bei der Sie Eingaben interaktiv lesen, und eine andere, bei der Sie sie aus einer Datei lesen oder während der Codeblockauswertung bereitstellen .
wvxvw

Antworten:

8

So was:

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

Erstellen Sie eine Datei in.txtim selben Verzeichnis wie die Org-Datei mit Inhalt 10.

abo-abo
quelle
7

Sie können Emacs bitten, die interaktive Eingabe stattdessen mithilfe eines benannten elispBlocks abzurufen. Übergeben Sie dann den gesammelten Wert mithilfe der folgenden :var c-variable=block-nameSyntax an den C ++ - Quellblock :

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

Beachten Sie, dass die Ausgaben von Quellblöcken als Zeichenfolgen übergeben werden, sodass wir sie in eine Ganzzahl konvertieren müssen, daher das atoiund das Extra #include.

erikstokes
quelle
1
Mach, wie es dir gefällt. Ihr Code ist jedoch an den Org-Modus gebunden, während meiner wörtlich kopiert und leicht kompiliert werden kann.
Abo-Abo
1
Danke @erikstrokes für diesen Beitrag; Ich hatte eine ähnliche Idee (benutze einen externen Block) und machte eine Mischung mit einer Abo-Abo-Lösung. Ich habe das Ergebnis als Antwort gepostet.
Lgen
4

Danke @ abo-abo für deine Hilfe. Ich bin Ihrem Vorschlag gefolgt, der richtig ist, und habe ihn sogar ein wenig erweitert, um nur meine Organisationsdatei zu bearbeiten (und die externe Eingabedatei automatisch zu erstellen). Die Idee ist, einen externen Codeblock (hier ein Bash-Skript mit dem Namen build_input_file) zu erstellen, der die Datendatei erstellt und sie automatisch aufruft, bevor der andere Block dank der :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
quelle