0

用 open3 回答 ruby​​ 中的 cli 提示? ”可能是重复的问题,但它没有答案。

我需要编写一个程序来编译和执行 C 程序,提供输入并返回输出。到目前为止,我想出了这个:

对于单输入:

Open3.popen3('one.exe') do |stdin, stdout, stderr|
  stdin.puts "45\n"
  STDOUT.puts stdout.gets
end

输出是:

Enter the temperature in degrees fahrenheit: The converted temperature is 7.222222

对于两个或更多输入:

Open3.popen3('two.exe') do |stdin, stdout, stderr|
  stdin.puts "45 45"
# This line works the same as the previous one.
# stdin.puts "45\r\n45"
  stdin.close

  STDOUT.puts stdout.gets
end

输出是:

Enter first number: Enter second number: Sum is 90

问题是,我没有取回我输入的输入。

有没有办法可以纠正它,或者可能有更好的方法来做到这一点?

4

1 回答 1

1

考虑一下:

使用以下命令创建输入文件:

cat > test.input
bar
baz

然后按CTRL+D终止输入,这将导致文件test.input被创建。

在同一目录中将此代码另存为test.rb

2.times do |i|
  user_input = gets.chomp
  puts "#{ i }: #{ user_input }"
end

使用以下代码运行代码:

ruby test.rb < test.input

你应该看到:

0: bar
1: baz

这样做的原因是因为gets读取 STDIN(默认情况下)寻找行尾,在这种情况下是字符尾随barand baz。如果我在 IRB 中加载输入文件,很容易看到文件的内容:

input = File.read('test.input')
=> "bar\nbaz\n"

2.times说要读取一行两次,所以它从文件中读取两行并继续,退出times循环。

这意味着您可以创建一个文件,将其通过管道传输到您的脚本中,而 Ruby 会做正确的事情。我可以将 test.rb 代码重写为:

puts `sh ./test.sh < #{ ARGV[0] }`

并创建test.sh

for i in 1 2
do
  read line
  echo $i $line
done

然后使用以下方法调用它:

ruby test.rb test.input

并得到:

1 bar
2 baz

由于反引号是调用子 shell 或运行代码的众多方法之一,因此您可以调整调用代码和/或子 shell 以读取文件。或者让 Ruby 读取输入并生成要调用的文件。或者使用 Expect 进行调查,但我不希望任何人这样做。

这应该有助于您走上正确的道路。

于 2016-03-07T20:49:36.173 回答