[comp.sys.amiga.programmer] SAS-C problem

fiffi@opal.cs.tu-berlin.de (Carsten Hoehne) (03/24/91)

fscanf has the following template

fsanf(File *file,char *format-string,...)

The scanf fscanf  sscanf routines of lc.lib  doesn't work as described in
the manual on page L96 ff.

There is stated that if the format-string includes white spaces then
white spaces are skipped in file. This description is similar to the
UNIX scanf routines.

Some examples  to illustrate the problem.

1. fscanf(file,"\n") must skip any white spaces in file

2. fscanf(file,"%d\n",&i) should try to read an int in Variable i and then
                          skip white spaces

3. fscanf(file,"\n%c",&c) must skip white spaces and then read a non blank
                          character in the Variable c

But ...

SAS-C fscanf ignores  any white spaces in the format-string so the above
examples are evaluated not in the corrcet  order.  
1. is a do nothing operation
2. does not skip blanks after reading i
3.  "    "    "   "     so c contains possible a blank character


I will not work around this problem, since the routines are described
correctly but implemented the wrong way.

I detected this problem by porting OMEGA from UNIX to the AMIGA for my
own. 
So other people have run in the same problem but they have possible
ignored it.

BTW is there any way to reach SAS via EMAIL?
    i have the version 5.1

I need an working version of fscanf very soon, when i started to port
some of my real programms from UNIX to AMIGA

so long
        Carsten

   
 
--
Carsten Hoehne    |  e-mail: fiffi@opal.cs.tu-berlin.de
Potsdamer Str.61  |          fiffi@tubopal.UUCP
1000 Berlin 30    |            ...!{unido,pyramid}!tub!opal!fiffi
-------Germany    |          fiffi%tubopal@DB0TUI11.BITNET

phil@adam.adelaide.edu.au (Phil Kernick) (03/25/91)

fiffi@opal.cs.tu-berlin.de (Carsten Hoehne) writes:

>fscanf has the following template
>fsanf(File *file,char *format-string,...)

[stuff deleted]

>3. fscanf(file,"\n%c",&c) must skip white spaces and then read a non blank
>                          character in the Variable c

This is not how scanf works with characters.  From the unix man pages...

     The control string usually  contains  conversion  specifica-
     tions,  which  are  used  to  direct interpretation of input
     sequences.  The control string may contain:

          1. White-space  characters  (SPACE,  TAB,  or  NEWLINE)
             which,  except  in  two cases described below, cause
             input to be read  up  to  the  next  non-white-space
             character.

     The conversion character indicates the interpretation of the
     input field; the corresponding pointer argument must usually
     be of a restricted type.  For a suppressed field, no pointer
     argument  is given.  The following conversion characters are
     legal:

          c    A character is expected; the  corresponding  argu-
               ment  should  be  a character pointer.  The normal
               skip over white space is suppressed in this  case;
               to read the next non-space character, use %1s.  If
               a field width is given, the corresponding argument
               should  refer  to a character array, and the indi-
               cated number of characters is read.


Notice that the "skip-whitespace" is not done with character arguments.
As the man page says, you must use %1s to get a single character after
the next whitespace, but remember, scanf with return a null terminated
string, so you will have to declare an array of char of length 2.  The
first to get your character and the second to take the \0.

Example:

        char c[2];
        fscanf(file, "%1s", c);

will do what you want.


Phil.

-- 
o|      ///   Phil Kernick              EMail:  phil@adam.adelaide.edu.au    |o
 |     ///    Departmental Engineer     Phone:  +618 228 5914                |
o| \\\///     Dept. of Psychology       Fax:    +618 224 0464                |o
 |  \///      University of Adelaide    Mail:   GPO Box 498 Adelaide SA 5001 |

jseymour@medar.com (James Seymour) (03/27/91)

In article <FIFFI.91Mar24165431@pc3.cs.tu-berlin.de> fiffi@opal.cs.tu-berlin.de writes:
>
> [stuff deleted...]
>
>fsanf(File *file,char *format-string,...)
>
>The scanf fscanf  sscanf routines of lc.lib  doesn't work as described in
>the manual on page L96 ff.
>
> [more stuff deleted...]
>
>Some examples  to illustrate the problem.
>
>1. fscanf(file,"\n") must skip any white spaces in file
>
>2. fscanf(file,"%d\n",&i) should try to read an int in Variable i and then
>                          skip white spaces
>
>3. fscanf(file,"\n%c",&c) must skip white spaces and then read a non blank
>                          character in the Variable c
>
> [still more stuff deleted...]
>
>I need an working version of fscanf very soon, when i started to port
>some of my real programms from UNIX to AMIGA
>

Carsten,

    What you have found is probably not a bug in the SAS/C library
    function so much as a "portability problem".

    From the scanf manual page for the SCO Xenix System 5 development
    system:

	----------------------------------------------------------------
	  The control string usually contains conversion
	  specifications, which	are used to direct interpretation of
	  input	sequences.  The	control	string may contain:

	  1. Blanks, tabs, or newlines which cause input to be read up
	     to	the next nonwhitespace character.

	  2. An	ordinary character (not	%), which must match the next
	     character of the input stream.
	----------------------------------------------------------------

    From "The C Programming Language" (original  K&R), Chapter 7, Section
    7.4 (pp. 148):

	----------------------------------------------------------------
	    The control string usually contains conversion specifications,
	which are used to direct interpretation  of input sequences.  The
	control string may contain:

	    Blanks, tabs, or newlines ("white space characters"), which
	    are ignored.

	    Ordinary characters (not %), which are expected to match
	    the next non-white space character of the input stream.
	----------------------------------------------------------------

    On the other hand...

    From "The C Programming Language", Second Edition (ANSI), C Reference
    Manual, Section B1.3 (pp. 245):

	----------------------------------------------------------------
	    The format string usually contains conversion specifications,
	which are used to direct interpretation  of input.  The format
	string may contain:

	    . Blanks or tabs, which are ignored.

	    . Ordinary characters (not %), which are expected to match
	      the next non-white space character of the input stream.
	----------------------------------------------------------------

	(The discussion of scanf in Chapter 7, Input and Output, Section
	 7.4 (pp. 157) agrees with the CRM).

    Note the lack of "newline", only blanks or tabs in the format
    string.  This implies that there was a change from K&R C to ANSI C,
    to wit: a newline in the format string is treated as an "ordinary
    character" now.  The SAS/C development package is the most ANSI-
    compatible package I've used to date.  If what I've surmised is
    correct, the SAS/C package is behaving correctly.

    Now, one has to wonder why in the world the author(s) of the afflicted
    code would have put *newlines* in the format string anyway.  Again,
    from the SCO Xenix scanf man page:

	----------------------------------------------------------------
	  A conversion specification directs the conversion of the
	  next input field; ...
	                ...  An	input field is defined as a string of
	  nonspace characters; it extends to the next inappropriate
	  character or until the field width, if specified, is
	  exhausted.  For all descriptors except ``['' and ``c'',
	  white	space preceding	an input field is ignored.
	----------------------------------------------------------------

    Again from the original K&R work:

	----------------------------------------------------------------
	A conversion specification directs the conversion of the next
	input field. ...
	... An input field is defined as a string on non-white space
	characters; it extends either to the next white space character
	of until the field width, if specified, is exhausted.  This
	implies that scanf will read across line boundaries to find its
	input, since newlines are white space.
	----------------------------------------------------------------

    Unless I'm missing something, the newlines in the conversion
    specification were superfluous.  Did someone neglect to RTFM?

    Lastly, an admonishment: most experienced C programmers know that
    it's unwise to use fscanf unless there's some over-riding reason to
    do so (although this may not help in your case).  Especially if the
    format of the input is not "fixed" (as is easily the case with input
    from stdin).  The reason?  fscanf will block indefinitely if it
    doesn't find the type of item it's looking for in the input stream
    (as per the conversion specification).  Or at least that was it's
    behaviour the last time I tried it :-).  Defensive programming
    technique demands that you get input lines into a string via some
    other vehicle, and then sscanf the string.  Admittedly, this is
    impractical for some applications, and this may the case for the
    thing you're working on.  Personally, ever since getting burned
    a couple of times by fscanf several years ago (having ignored the
    cautionary notes in the C tutorial I first read :-)), I avoid it
    like the plague.  And when I do have to use it, I surround the
    fscanf statements with *lots* of anti-bugging code to prevent an
    input hangup.

    I hope this helps you out.  Good luck!
-- 
Jim Seymour				| Medar, Inc.
...!uunet!medar!jseymour		| 38700 Grand River Ave.
jseymour@medar.com			| Farmington Hills, MI. 48331
CIS: 72730,1166  GEnie: jseymour	| FAX: (313)477-8897