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