Org Mode Babel - оцінка інтерактивного кодового блоку


12

Я хотів би оцінити в режимі org блоки вихідного коду в C ++, що містять інструкції "cin", але я не можу знайти інтерактивну оцінку (із введенням користувача) під час оцінювання. Приклад коду:

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

Чи можливо провести таку інтерактивну оцінку чи змоделювати (надавши вихідному коду підроблений вклад)?


Вам дійсно потрібно, щоб він був інтерактивним, чи вам просто потрібно дати йому якийсь вклад, який ви, можливо, вже знаєте заздалегідь, тільки не в цьому кодовому блоці? Другий випадок простіше: ви могли використовувати :var varname=valueв заголовку. У другому випадку ви все одно можете використовувати :var, але замість значення використовуйте інший блок коду з функцією ELisp, який запитує введення.
wvxvw

Дякую @wvxvw за вашу відповідь; Що я хочу зробити, це зробити документ із деякими прикладами програми для студентів, і тому я хотів би зберегти блок вихідного коду "як є"; тому моїм уподобанням було б другий ви згаданий випадок; Я спробую дотримуватися вашої пропозиції (використовувати: var та код elisp для запиту на введення), чи є у вас посилання чи приклад такого дзвінка?
Lgen

О, вибачте, було трохи непорозуміння. Другий приклад використовує Emacs для читання введення, але Babel не зателефонує на програму C ++ таким чином, щоб дозволити взаємодію. Єдине, про що я можу подумати, це те, що якщо ви додасте до свого коду якусь "поліморфну" функцію, яка має дві реалізації: одну, де ви читаєте вхід інтерактивно, та іншу, де ви читаєте її з файлу або надаєте під час оцінки блоку коду .
wvxvw

Відповіді:


8

Подобається це:

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

Створіть файл in.txtу тому самому каталозі, що і файл Org, із вмістом 10.


7

Ви можете попросити Emacs отримати інтерактивний ввід, а не використовувати названий elispблок. Потім передайте зібране значення блоку C ++ souce за допомогою :var c-variable=block-nameсинтаксису:

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

Зауважте, що вихідні блоки джерела передаються навколо як рядки, тому нам доведеться перетворити його на ціле число, отже, atoiі додаткове #include.


1
Роби як хочеш. Однак ваш код прив’язаний до Org-режиму, тоді як мій можна копіювати дословно і легко компілювати.
або-або

1
Дякуємо @erikstrokes за цей внесок; У мене була схожа ідея (використовуйте зовнішній блок) і зробила суміш з розчином або-або. Я опублікував результат як відповідь.
Lgen

4

Дякуємо @ Або-Або за вашу допомогу. Я дотримувався вашої пропозиції, яка є правильною, і навіть трохи покращила її, щоб редагувати лише мій файл org (і автоматично створювати зовнішній вхідний файл). Ідея полягає у створенні зовнішнього блоку коду (тут скрипт bash з назвою build_input_file), який створює файл даних та викликає його автоматично перед оцінкою іншого блоку завдяки :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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.