Org Mode Babel - Avaliação interativa de blocos de código

12

Gostaria de avaliar nos blocos de código-fonte do modo organizacional em C ++ que contêm instruções "cin", mas não consigo encontrar uma maneira de fazer uma avaliação interativa (com a entrada do usuário) durante a avaliação. Exemplo de código:

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

É possível ter uma avaliação interativa ou simular (fornecendo ao código fonte uma entrada falsa)?

Lgen
fonte
Você realmente precisa que seja interativo ou precisa fornecer alguma entrada que você já conheça com antecedência, mas não neste bloco de código? O segundo caso é mais fácil: você pode usar :var varname=valueno cabeçalho. No segundo caso, você ainda pode usar :var, mas no lugar do valor, use outro bloco de código com uma função ELisp que solicita entrada.
Wdxvw
Obrigado @wvxvw pela sua resposta; O que eu quero fazer é criar um documento com alguns exemplos de programas para os alunos e, portanto, gostaria de manter o bloco do código-fonte "como está"; então minha preferência seria o segundo caso que você mencionou; Vou tentar seguir sua sugestão (para usar: var e um código elisp para solicitar entrada), você tem um link ou um exemplo de uma chamada?
LG
Desculpe, houve um pouco de mal-entendido. O segundo exemplo usaria o Emacs para ler a entrada, mas Babel não chamará o programa C ++ da maneira que permite a interação. A única coisa em que consigo pensar é que, se você adicionar alguma função "polimórfica" ao seu código, que possui duas implementações: uma, onde você lê a entrada interativamente, e outra, onde você lê o arquivo ou fornece durante a avaliação do bloco de código .
wvxvw

Respostas:

8

Como isso:

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

Crie um arquivo in.txtno mesmo diretório que o arquivo Org, com conteúdo 10.

abo-abo
fonte
7

Você pode solicitar ao Emacs para obter a entrada interativa usando um elispbloco nomeado . Em seguida, passe o valor coletado para o bloco de código C ++ usando a :var c-variable=block-namesintaxe:

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

Note que as saídas dos blocos de origem são passadas como strings, então temos que convertê-lo em um número inteiro, daí o atoie o extra #include.

erikstokes
fonte
11
Faça como quiser. No entanto, seu código está vinculado ao modo Org, enquanto o meu pode ser copiado e colado literalmente e prontamente compilado.
abo-abo
11
Obrigado @erikstrokes por esta contribuição; Eu tive uma idéia semelhante (use um bloco externo) e fiz uma mistura com a solução abo-abo. Postei o resultado como resposta.
Lgen 27/08/15
4

Obrigado @ abo-abo por sua ajuda. Segui sua sugestão correta e até a aprimorei um pouco para editar apenas meu arquivo organizacional (e criar automaticamente o arquivo de entrada externo). A idéia é criar um bloco de código externo (aqui um script bash chamado build_input_file) que cria o arquivo de dados e chamá-lo automaticamente antes de avaliar o outro bloco graças ao :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
fonte