binary stdin/stdout 
Author Message
 binary stdin/stdout

  A friend and I were discussing some tools he is writing and we came
across a problem:

        How does one write portable code to access stdin and stdout in
        binary mode...?

  I know this isn't a problem if you just deal with ***x systems, but
what he wants to do requires being able to port this across many
different machines.  Anyone have a solution?

  PS:  Since I quite often don't have time to read news on the net,
email responses will be cheerfully accepted...  Anything really useful
I'll summarize and repost to the net..

  Advthanksance...

---



Fri, 19 Jun 1992 10:32:00 GMT  
 binary stdin/stdout

Quote:

>    How does one write portable code to access stdin and stdout in
>    binary mode...?

You don't.  The three standard streams are preopened as text streams,
not binary, and there is no standard mechanism for changing this.  In
fact it may not even be possible to treat a text connection as binary
in some operating system environments.


Fri, 19 Jun 1992 07:49:00 GMT  
 binary stdin/stdout
I just made this C comment {*filter*}, I tried it on it self and it works
ok. If any one finds code it pukes on tell me (there is probably still
something I missed).

----------------------cut here-------------------
/* Public domain C comment {*filter*} created by Lawrence Foard */
#include <stdio.h>
char *a="/* this is a test 'of the emergency \" comment {*filter*} \\ \'*/";
/* this is a'{*filter*}\' "comment" meant / * to really confuse it"*//*\*/
int no_com()
 {
  int c;
  static int quote=0,squote=0,slash=0;
  c=getc(stdin);
  if (slash || (c=='\\'))
   {
    slash=!slash;
    return(c);
   }
  if ((quote^=((c=='"') && !squote)) ||
      (squote^=((c=='\''/*\ and right here two \*/) && !quote)))
   return(c);
  if (c=='/')
   if ((c=getc(stdin))!='*')
    {
     ungetc(c,stdin);
     return('/');
    }
   else
    {
     do
      while(getc(stdin)!='*');
     while(getc(stdin)!='/');
     return(no_com());
    }
   return(c);
  }  

main()
 {
  int c;
  while((c=no_com())!=EOF)
   fputc(c,stdout);
 }  
 --
Disclaimer: My school does not share my views about fortran.
            FORTRAN does not share my views about my school.



Mon, 17 Aug 1992 03:51:00 GMT  
 binary stdin/stdout


Quote:
> I just made this C comment {*filter*}, I tried it on it self and it works
> ok. If any one finds code it pukes on tell me (there is probably still
> something I missed).

It pukes ... try:

        /***/ main() {printf("hi there\n");} /* */

Score, anyone? (recent postings tested on K&R-I-syntax code)

        sed        1/1 correct
        Lex        2/2 correct
        C          2/2 wrong

Hmmm.

John Rupley



Mon, 17 Aug 1992 00:57:00 GMT  
 binary stdin/stdout

Quote:

>Score, anyone? (recent postings tested on K&R-I-syntax code)

>    sed        1/1 correct
>    Lex        2/2 correct
>    C          2/2 wrong

This sounds like a CHALLENGE!  :-)

I wrote the following working against the ten-minute spaghetti clock.
It is slightly tested, and probably works, with the exception of

        #include <some/*weird:file[syntax]>

(and unclosed comments, etc., in included files).  It is more
permissive than real C (allowing newlines in string and character
constants, and allowing infintely long character constants) but should
not get anything wrong that cpp gets right.

Of course, there are no comments in it. :-)

#include <stdio.h>

enum states { none, slash, quote, qquote, comment, cstar };

main()
{
        register int c, q = 0;
        register enum states state = none;

        while ((c = getchar()) != EOF) {
                switch (state) {
                case none:
                        if (c == '"' || c == '\'') {
                                state = quote;
                                q = c;
                        } else if (c == '/') {
                                state = slash;
                                continue;
                        }
                        break;
                case slash:
                        if (c == '*') {
                                state = comment;
                                continue;
                        }
                        state = none;
                        (void) putchar('/');
                        break;
                case quote:
                        if (c == '\\')
                                state = qquote;
                        else if (c == q)
                                state = none;
                        break;
                case qquote:
                        state = quote;
                        break;
                case comment:
                        if (c == '*')
                                state = cstar;
                        continue;
                case cstar:
                        if (c != '*')
                                state = c == '/' ? none : comment;
                        continue;
                default:
                        fprintf(stderr, "impossible state %d\n", state);
                        exit(1);
                }
                (void) putchar(c);
        }
        if (state != none)
                fprintf(stderr, "warning: file ended with unterminated %s\n",
                        state == quote || state == qquote ?
                                (q=='"' ? "string" : "character constant") :
                        "comment");
        exit(0);

Quote:
}

--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)



Mon, 17 Aug 1992 05:43:00 GMT  
 binary stdin/stdout
++ This sounds like a CHALLENGE!  :-)

Below is a *real* challenge, for all those in net land with extra time
on their hands during easter and spring break!  I've included below a
very efficient sorting routine, together with a nifty
`sort-program-correctness-tester.'

======================================================================

            Your challenge, should you wish to accept it,
          is to write a faster, pseudo-portable, and correct
          sort routine that fulfills the same specification
                      as the one included below.

======================================================================

Pseduo-portable is eclectically defined as ``compiling and executing
correctly with GNU GCC, AT&T cfront, and GNU G++!'' Actually, K&R C is
fine too, I just didn't feel like cluttering up my program with
#ifdef's everywhere....  The point here is to emphasize creating a
clever algorithm, without being overly dependent on the machine or
compiler.  When I compare the final entries, I will use GCC, with the
-O and -fstrength-reduce options enabled.

To make this interesting, assume that the input sizes to the supplied
driver program are: 100,000, 500,000, and 1,000,000

Here are the my results on a Sun 4/260, using G++ 1.34.2 with -O
----------------------------------------
sorttest 100000
time = 1.530
sorttest 500000
time = 8.820
sorttest 1000000
time = 19.130
----------------------------------------

Naturally, not everyone has a Sun 4 ;-).  So to make this fair I'll
collect entries, time them on an otherwise empty Sun 4/260, and report
the results.  Naturally, I'd be interested in seeing how your programs
perform on other machines, too.  If anyone feels that the rules aren't
clear enough, feel free to elaborate them.  I'm mostly interested in
seeing whether anyone can beat the following sorting algorithm for
large input values.

If enough people enter good programs, I'll archive them and make
them available for anonymous FTP.

Good luck!!!

   Doug        
---
On a clear day, under blue skies, there is no need to seek.
And asking about Buddha                +------------------------+

With loot in your pocket.              | office: (714) 856-4043 |
----------------------------------------------------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#               "End of shell archive."
# Contents:  checksort.c sort.c test.c Makefile

PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'checksort.c' -a "${1}" != "-c" ; then
  echo shar: Will not clobber existing file \"'checksort.c'\"
else
echo shar: Extracting \"'checksort.c'\" \(3067 characters\)
sed "s/^X//" >'checksort.c' <<'END_OF_FILE'
X/* Efficient and general mechanism for testing correctness of sort routines.
X   Please excuse the lack of comments.  I wrote this long ago, before
X   learning the importance of documentation (the hard way!) ;-). */
X
Xtypedef struct node
X{
X  int          item;
X  struct node *next;
X} node;
X
Xint   *range_buf;
Xnode **hash_buf;
Xint    buf_size;
Xnode  *mem_stack;
Xnode  *stack_top;
Xnode   sentinel;
Xnode  *sentinel_ptr = &sentinel;
X
Xint
Xfree_mem_and_exit(int status)
X{
X  free (mem_stack);
X  free (hash_buf);
X  free (range_buf);
X  return status;
X}  
X
Xint
Xinit_hash_buf (void)
X{
X  register int i;
X  
X  if (!(hash_buf = (node **) malloc (buf_size * sizeof (node *))))
X    return 0;
X
X  for (i = 0;i < buf_size;i++)
X    hash_buf[i] = sentinel_ptr;
X
X  return (mem_stack = stack_top = (node *) calloc (buf_size, sizeof (node))) != 0;
X}
X
Xnode *
Xmake_node (int item)
X{
X  node *temp = stack_top++;
X  
X  temp->item = item;
X  return temp;
X}
X
Xint
Xhash_value (int item)
X{
X  return item % buf_size;
X}
X
Xvoid
Xhash_insert (int item)
X{
X  int loc           = hash_value (item);
X  node *new_node = make_node (item);
X  
X  new_node->next = hash_buf[loc];
X  hash_buf[loc]  = new_node;
X}
X
Xint
Xremove_node (int item)
X{
X   int      loc  = hash_value (item);
X   node *temp = hash_buf[loc];
X   node *prev = 0;
X
X   for (sentinel.item = item; temp->item != item; prev = temp, temp = temp->next)
X     ;
X  
X   if (temp == sentinel_ptr)
X     return 0;
X   else if (!prev)
X     hash_buf[loc] = temp->next;
X   else
X     prev->next = temp->next;
X
X   return 1;
X}
X
Xint
Xdelete_buf(int *base)
X{
X  int i;
X  
X  for (i = 0; i < buf_size; i++)
X    if (!remove_node (base[i]))
X      return 0;
X
X  for (i = 0; i < buf_size; i++)
X    if (hash_buf[i] != sentinel_ptr)
X      return 0;
X
X  return 1;
X}
X
Xint
Xcheck_sort (int *original, int *base, int size)
X{
X  int range = base[size - 1];
X
X  if ((buf_size = size) >= range)
X    {
X      if (!(range_buf = (int *) calloc (range, sizeof (int))))
X        return -1;
X      else
X        {
X          int i;
X        
X          for (i = 1; i < buf_size; i++)
X            if ((base[i] < base[i - 1]) || base[i - 1] > range || base[i - 1] < 0)
X              return free_mem_and_exit (0);
X            else
X              ++range_buf[base[i - 1]];
X
X          ++range_buf[base[buf_size - 1]];
X        
X          for (i = 0; i < buf_size; i++)
X            if (range_buf[original[i]] <= 0)
X              return free_mem_and_exit (0);
X            else
X              --range_buf[original[i]];
X
X          for (i = 0; i < range; i++)
X            if (range_buf[i] != 0)
X              return free_mem_and_exit (0);
X        
X        }
X    }
X  else if (!init_hash_buf ())
X    return -1;
X  else
X    {
X      int i;
X      
X      for (i = 1; i < buf_size; i++)
X        {
X          if (base[i] < base[i - 1])
X            return free_mem_and_exit (0);
X          else
X            hash_insert(base[i - 1]);
X        }
X  
X      hash_insert (base[buf_size - 1]);
X      if (!delete_buf (original))
X        return free_mem_and_exit (0);
X    }  
X  return free_mem_and_exit (1);
X}
END_OF_FILE
if test 3067 -ne `wc -c <'checksort.c'`; then
    echo shar: \"'checksort.c'\" unpacked with wrong size!
fi
# end of 'checksort.c'
fi
if test -f 'sort.c' -a "${1}" != "-c" ; then
  echo shar: Will not clobber existing file \"'sort.c'\"
else
echo shar: Extracting \"'sort.c'\" \(5893 characters\)
sed "s/^X//" >'sort.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <ctype.h>
X
X/* the next 5 #defines implement a very fast in-line stack abstraction       */
X
X#define MAKE_STACK(S) ((stack_node *) malloc (sizeof(stack_node) * (S)))
X#define PUSH(LOW,HIGH) do {top->lo = LOW;top->hi = HIGH;top++;} while (0)
X#define POP(LOW,HIGH)  do {--top;LOW = top->lo;HIGH = top->hi;} while (0)
X#define STACK_NOT_EMPTY (stack < top)                
X#define SWAP(A,B) do {int _temp = (A);(A) = (B);(B) = _temp;} while (0)
X
X/* Discontinue quicksort algorithm when partition gets below this size.
X   This particular magic number was chosen to work best on a Sun 4/260. */
X#define MAX_THRESH 15
X
X#ifdef __GNUG__
X#define MAX(X,Y) ((X) >? (Y))
X#else
X#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
X#endif
X
X/* Data structure for stack of unfulfilled obligations. */
Xtypedef struct
X{
X  int *lo;
X  int *hi;
X} stack_node;
X
X/* Once main array is partially sorted by quicksort the remainder is
X   completely sorted using insertion sort, since this is efficient
X   for partitions below MAX_THRESH size. BASE points to the beginning
X   of the array to sort, and END_PTR points at the very last element in
X   the array (*not* one beyond it!). */
X
Xinline static void
Xinsert_sort(int *base, int *end_ptr)
X{
X  int *run_ptr;
X  int *tmp_ptr = end_ptr;
X  int *thresh  = MAX (base, end_ptr - MAX_THRESH);
X
X  /* Find the smallest element in the first threshold and put it at the
X     end of the array.  This is guaranteed to be the smallest element in
X     the array, and it speeds up the inner loop of insertion sort. */
X
X  for (run_ptr = tmp_ptr - 1; run_ptr >= thresh; run_ptr--)
X    if (*run_ptr > *tmp_ptr)
X      tmp_ptr = run_ptr;
X
X  SWAP (*tmp_ptr, *end_ptr);
X
X  /* Typical insertion sort, but we run from the `right-hand-side'
X     downto the `left-hand-side.' */
X
X  for (run_ptr = end_ptr - 1; run_ptr > base; run_ptr--)
X    {
X      int temp = *(tmp_ptr = run_ptr - 1);
X
X      /* Select the correct location for the new element,
X         by sliding everyone down by 1 to make room! */
X
X      while (temp > *++tmp_ptr)
X        tmp_ptr[-1] = *tmp_ptr;
X
X      tmp_ptr[-1] = temp;
X    }
X}
X
X/* Return the median value selected from among the
X   LOW, MIDDLE, and HIGH.  Rearrange LOW and HIGH so
X   the three values are sorted amongst themselves.
X   This speeds up later work... */
X
Xinline static int
Xfind_pivot(int *low, int *high)
X{
X  int *middle = low + ((high - low ) >> 1);
X
X  if (*middle < *low)
X    SWAP (*middle, *low);
X  if (*high < *middle)
X    SWAP (*middle, *high);
X  else
X    return *middle;
X
X  if (*middle < *low)
X    SWAP (*middle, *low);
X
X  return *middle;
X}
X
X/* Order elements using quicksort.  This implementation incorporates
X   4 optimizations discussed in Sedgewick:
X  
X   1. Non-recursive, using an explicit stack of log (n) pointers that
X      indicate the next array partition to sort.
X
X   2. Choses the pivot element to be the median-of-three, reducing
X      the probability of selecting a bad pivot value.
X
X   3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
X      insertion sort to sort within the partitions.  This is a
X      big win, since insertion sort is
...

read more »



Mon, 17 Aug 1992 08:18:00 GMT  
 binary stdin/stdout

Quote:


> >Score, anyone? (recent postings tested on K&R-I-syntax code)

> >       sed        1/1 correct
> >       Lex        2/2 correct
> >       C          2/2 wrong

> This sounds like a CHALLENGE!  :-)

Unclear again (sob :-).  Meant it as a comment, implying the VIRTUES of
Lex (and even sed :-) for pattern matching.  Contest-wise, your C code
is the first correct as initially posted, it runs faster than the previous
postings (after correction of the latter), and one can follow the neat
state-machine implementation at first reading.

Quote:
> I wrote the following working against the ten-minute spaghetti clock.

Wow! It took me longer to test it.

For what its worth (as COMMENTARY -- please, no contest), counting new
postings, too:

      sed, awk        2/3 correct as first posted (test vs K&R-I-type code)
      Lex             2/3
      C               1/3

Hmmm.  Conclusion?  The probability of any particular piece of code being
correct is independent of language and is a toss-up (:-)?  

But I still like Lex for this particular type of problem.

John Rupley



Mon, 17 Aug 1992 20:59:00 GMT  
 
 [ 10 post ] 

 Relevant Pages 

1. Set stdin/stdout in binary on UNIX

2. Binary and Text Modes and Stdin/Stdout

3. how are stdin/stdout set?

4. CRC16 stdin / stdout

5. Stdin, Stdout and Stderr

6. redirecting stdin/ stdout to use files

7. changing is stdin,stdout,stderr?

8. HELP: interacting with another program through stdout/stdin

9. stdin/stdout redirection mystericals

10. stdin, stdout, fprintf

11. how to redirect stdin and stdout to another file descriptor

12. system() - stdin / stdout

 

 
Powered by phpBB® Forum Software