views:

907

answers:

3

I'm looking to write a pair of utilities that read in a newline separated list of integers on stdin and output their binary (4 byte) equivalent to stdout, and vice versa.

My first thought was a simple bash/linux command that would do this, but I was unable to find one. My second thought was to do this in C++, but I can't figure out how to change stdin or stdout to a binary stream.

Any thoughts on a good way to do this? I'm impartial to any particular programming language.

+2  A: 

You don't need to "change stdout to binary", just output binary to it. This will certainly confuse e.g. a terminal emulator connected to that stream, but that is to be expected.

A plain loop of fscanf() to read each integer, followed by a fwrite() to write it out should work. Beware of endianness issues though, you might want to output each byte separately.

unwind
It's worth mentioning endian-ness (that's why Unix prefers text), though where you are piping to a program, both are on the same machine. If you used a socket instead (to a program on a separate machine) - then endian-ness comes into play.
Jonathan Leffler
+3  A: 

In Perl, you could just try:

perl -ne 'chomp; print pack 'i', $_;'

That will give you a host native signed integer of at least 32 bits, but possibly more depending on your local C compiler.

Other options to pack can go in place of the 'i', such as 'l' which will give you a signed long, which should be 32-bits. And there yet more options for little-endian or big-endian.

For the full description, please see http://perldoc.perl.org/functions/pack.html.

And here's your solution in C, in case you want to do it the boring way. :)

#include <stdio.h>

int main () {
   int x;

   while (fscanf(stdin, "%i", &x)) {
      fwrite(&x, sizeof(x), 1, stdout);
   }

   return 0;
}
jbourque
Thanks, that perl bit is great.
Rich
No worries... glad I could help.
jbourque
A: 

On Unix and its derivatives, there is no need to be concerned about whether the stdin or stdout are 'binary' mode - binary and text modes are the same. I've not conducted extensive testing on Windows, but under Cygwin, I've not noticed any issues there, either.

Jonathan Leffler
Right, I guess my problem was that I didn't understand how to output the number "in binary mode". 'cout << 256;' will output the 3 ascii characters "256" not the binary equivalent.
Rich
@Rich: yes; cout assumes text and converts stuff to text by default. The analog of C's `fwrite()` should be used instead.
Jonathan Leffler