"用open3回答Ruby中的cli提示?"是一个可能的重复问题,但它没有答案。
我需要编写一个程序来编译和执行 C 程序,提供输入并返回输出。到目前为止,我想出了这个:
对于单输入:
Open3.popen3('one.exe') do |stdin, stdout, stderr|
stdin.puts "45n"
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 "45rn45"
stdin.close
STDOUT.puts stdout.gets
end
输出为:
Enter first number: Enter second number: Sum is 90
问题是,我没有拿回我输入的输入。
有没有办法纠正它,或者有更好的方法可以做到这一点?
考虑一下:
使用以下方法创建输入文件:
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(默认情况下)寻找行尾,在这种情况下是字符尾随 bar
和 baz
。如果我在IRB中加载输入文件,很容易看到文件的内容:
input = File.read('test.input')
=> "barnbazn"
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 或运行代码的众多方法之一,因此您可以调整调用代码和/或子代码以读取文件。或者让 Ruby 读取输入并生成要调用的文件。或者使用预期进行调查,但我不希望任何人这样做。
这应该有助于你走上正确的道路。