Org Mode Babel - การประเมินการบล็อกรหัสแบบโต้ตอบ


12

ฉันต้องการประเมินในบล็อกซอร์สโค้ดโหมดองค์กรใน 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 เพื่ออ่านอินพุต แต่บาเบลจะไม่เรียกโปรแกรม C ++ ในลักษณะเช่นอนุญาตการโต้ตอบ สิ่งเดียวที่ฉันคิดได้ก็คือถ้าคุณเพิ่มฟังก์ชั่น "polymorphic" ลงในโค้ดของคุณซึ่งมีการใช้งานสองแบบ: หนึ่งที่คุณอ่านอินพุตแบบโต้ตอบและอีกอันหนึ่งที่คุณอ่านจากไฟล์หรือให้ในระหว่างการประเมินโค้ดบล็อก .
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.txt10


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-mode ในขณะที่ของฉันสามารถคัดลอกวางคำต่อคำและรวบรวมได้อย่างง่ายดาย
abo-abo

1
ขอบคุณ @erikstrokes สำหรับการสนับสนุนนี้ ฉันมีความคิดที่คล้ายกัน (ใช้บล็อกภายนอก) และสร้างผสมกับโซลูชัน abo-abo ฉันโพสต์ผลลัพธ์เป็นคำตอบ
Lgen

4

ขอบคุณ @ abo-abo สำหรับความช่วยเหลือของคุณ ฉันได้ทำตามคำแนะนำของคุณซึ่งถูกต้องแล้วและปรับปรุงให้ดีขึ้นเล็กน้อยเพื่อแก้ไขเฉพาะไฟล์ org ของฉัน (และเพื่อสร้างไฟล์อินพุตภายนอกโดยอัตโนมัติ) ความคิดที่จะสร้างการป้องกันรหัสภายนอก (ที่นี่สคริปต์ทุบตีชื่อ 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.