# Ruby C extension/wrapper around C function that uses scanf

**URL:** <https://www.ruby-forum.com/t/ruby-c-extension-wrapper-around-c-function-that-uses-scanf/97691>\
**Category:** Ruby\
**Created:** [July 9, 2006, 6:50pm UTC](https://www.ruby-forum.com/t/ruby-c-extension-wrapper-around-c-function-that-uses-scanf/97691 "2006-07-09T18:50:51Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![1gor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/1/b9bd4f/32.png) [@1gor](https://www.ruby-forum.com/u/1gor)\
**Post date:** [July 9, 2006, 6:50pm UTC](https://www.ruby-forum.com/t/ruby-c-extension-wrapper-around-c-function-that-uses-scanf/97691/1 "2006-07-09T18:50:51Z")

</div>

I need Ruby to access a set of external command line applications for  
dataseries analysis. Each of these little apps simply reads data from  
stdin and then outputs processed results to stdout (using scanf and  
printf, they are all written in C).

These functions have to be accessed repeatedly when iterating over  
large chunks of data, so accessing them through the pipe (popen or  
popen3) doesn’t work. Launching/closing an external process 3000 times  
in a row results in errors. And that’s not efficient. So I have to  
write extension for each of those little C programs, a wrapper of  
sorts.

I have learned how to write and compile an extension for Ruby. I can  
import an extension, pass an array of data to it and return some data  
from the extension. The problem is that I have no C experience and  
dread thinking of having to replace each ‘scanf’ routine with my custom  
array of imported data (memory allocation, writing iterator etc.). Each  
input function here starts with:

```
 while (scanf("%lf", &y) == 1) { ... etc.

```

and then follows to process input data, handle cases with input buffer  
is too large etc. I would very much like to leave these input()  
functions as they are and just feed them my data from Ruby code.

Is it possible to fill stdin buffer with data from Ruby code and then  
simply call existing C function that uses ‘scanf’? I couldn’t simply  
assign an array to $stdin variable in Ruby, gave TypeError (File  
expected)…

---

<div class="post-metadata">

**Author:** ![1gor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/1/b9bd4f/32.png) [@1gor](https://www.ruby-forum.com/u/1gor)\
**Post date:** [July 9, 2006, 7:37pm UTC](https://www.ruby-forum.com/t/ruby-c-extension-wrapper-around-c-function-that-uses-scanf/97691/2 "2006-07-09T19:37:06Z")

</div>

1gor wrote:

> I need Ruby to access a set of external command line applications for  
> dataseries analysis. Each of these little apps simply reads data from  
> stdin and then outputs processed results to stdout (using scanf and  
> printf, they are all written in C).
> 
> These functions have to be accessed repeatedly when iterating over  
> large chunks of data, so accessing them through the pipe (popen or  
> popen3) doesn’t work.

Do they need changing arguments? Otherwise you could just start an  
instance of each via popen and then reuse that throughout the whole  
program. Or do these programs detect end of input data via EOF on  
STDIN?

> Launching/closing an external process 3000 times  
> in a row results in errors. And that’s not efficient.

Yeah, true.

> ```
> while (scanf("%lf", &y) == 1) { ... etc.
> 
> ```
> 
> and then follows to process input data, handle cases with input buffer  
> is too large etc. I would very much like to leave these input()  
> functions as they are and just feed them my data from Ruby code.
> 
> Is it possible to fill stdin buffer with data from Ruby code and then  
> simply call existing C function that uses ‘scanf’? I couldn’t simply  
> assign an array to $stdin variable in Ruby, gave TypeError (File  
> expected)…

Hm, I’m not a seasoned C programmer either, so I cannot give you a  
definitive answer to this. However, I doubt that you can simply inject  
stuff into stdin.

Here are two more ideas:

1. Rewrite your programs to act as if they saw EOF from stdin when they  
receive a certain signal (say SIGUSR1). That way you could use a single  
process throughout your whole Ruby script with popen and just need to  
send the signal at certain points in time. You could even change  
behavior to use the first line read from the pipe / stdin as command  
line arguments.

2. If it’s feasible rewrite the processing in Ruby. I guess you want to  
use a C program for certain reasons - these might be performance, not  
having to rewrite the code or whatever. If it’s not performance then  
maybe you can replace the stuff with 10% LOC in Ruby.

Kind regards

```
robert
```

---

<div class="post-metadata">

**Author:** ![1gor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/1/b9bd4f/32.png) [@1gor](https://www.ruby-forum.com/u/1gor)\
**Post date:** [July 11, 2006, 3:56am UTC](https://www.ruby-forum.com/t/ruby-c-extension-wrapper-around-c-function-that-uses-scanf/97691/3 "2006-07-11T03:56:45Z")

</div>

Go through the source code of your external apps, and replace each  
scanf() with sscanf(). (sscanf() reads from a string instead from  
standard input). Then you can make the Ruby wrappers and pass a string  
to each function. For example:

void old\_external\_app()  
{  
float x;  
scanf("%f %f…",&x,…);  
…  
printf("%f",x);  
}

void new\_external\_app(char \*input\_str, char \*output\_str)  
{  
float x;  
sscanf( input\_str, “%f %f…”,&x,…); // the same, except 1st arg  
…  
sprintf( output\_str, “%f”, x);  
}
