0

I am writing a program which execute an other program written in c, here is my first try

require 'Open3'

system 'tcc temp.c'

Open3.popen3('temp.exe') do |stdin, stdout, stderr|
   stdin.puts '21\n'
   STDOUT.puts stdout.gets
end

actual output:

Enter the temperature in degrees fahrenheit: The converted temperature is -6.11

desired output:

Enter the temperature in degrees fahrenheit: 21
The converted temperature is -6.11

and if you know a better way to do that please tell me, i am new to ruby.

Azam Ikram
  • 185
  • 1
  • 1
  • 10
  • 2
    I'm not sure pipes are what you really need here. Have you taken a look at the [PTY module](http://ruby-doc.org/stdlib-2.3.0/libdoc/pty/rdoc/PTY.html)? – Todd A. Jacobs Feb 22 '16 at 00:20
  • yeah! pty was giving the same output, and it is only for linux so that's why i am using this method. – Azam Ikram Feb 22 '16 at 02:32

2 Answers2

1

You seem to have at least two potential issues:

  1. Your newline will not expand inside single quotes. To include a newline within a string, you need to use double-quotes such as "21\n".
  2. In some cases, you actually need a carriage return rather than a newline. This is especially true when trying to do Expect-like things with a terminal. For example, you may find you need \r instead of \n in your string.

You definitely need to fix the first thing, but you may need to try the second as well. This is definitely one of those "your mileage may vary" situations.

Todd A. Jacobs
  • 81,402
  • 15
  • 141
  • 199
1

It seems like you're expecting 21 to appear on your screen because it does when you run temp.exe and type in 21. The reason it appears on your screen under those circumstances is that you're typing them into your shell, which "echoes" back everything you type.

When you run the program via Ruby, though, there's no shell and no typing, so 21 doesn't appear on your screen even though it's correctly being sent to the program's standard input.

The simplest solution is pretty simple. Just write it to Ruby's standard output as well:

require 'Open3'

system 'tcc temp.c'

Open3.popen3('temp.exe') do |stdin, stdout, stderr|
  STDOUT.puts "21"
  stdin.puts '"21"
  STDOUT.puts stdout.gets
end

(You'll note that I took out \nIO#puts adds that for you.)

This is a little repetitive, though. You might define a simple method to take care of it for you:

def echo(io, *args)
  puts *args
  io.puts *args
end

Then:

Open3.popen3('temp.exe') do |stdin, stdout, stderr|
  echo(stdin, "21")
  puts stdout.gets
end
Jordan Running
  • 102,619
  • 17
  • 182
  • 182
  • Thank you for your response, but when i do 'STDOUT.puts "21"' it just print 21 before the output from the stdout.gets and the rest is the same as it was before. – Azam Ikram Feb 22 '16 at 02:18