gwyn@brl-smoke.UUCP (04/03/86)
In article <1740@ittatc.ATC.ITT.UUCP> yoda@ittatc.ATC.ITT.UUCP (Todd C. Williams [Jedi Knight]) writes: >Is it possible to use gets() after scanf() ? >Is it a good idea to try to use gets() after scanf() ? >It doesn't work, so I tried adding "fflush(stdin);" >just before the gets(), but that doesn't help either. >If I do 2 "gets(str)"'s in a row, the second one works. > >Apparently, the scanf() is reading UP TO the newline, but >leaving that newline in the buffer; the gets() sees the >newline and thinks it is finished. scanf() does whatever you tell it to with the input stream then stops. If you make it eat newlines, it will. There should be no problem mixing any of the STDIO input methods. However, it sounds to me like your application would be programmed better with the following scheme: while get-a-line-using-fgets parse-line-with-sscanf By the way, don't use gets(); your input buffer can be overrun if an input line is very long, resulting in unpredictable malfunctioning of your application. When you use fgets(), it is often wise to test the last character in the record and if it is a newline, replace it with a 0 string terminator before parsing the record. Since this advice is independent of UNIX, I'm cross-posting to net.lang.c.
guy@sun.uucp (Guy Harris) (04/06/86)
> However, it sounds to me like your application would be > programmed better with the following scheme: > > while get-a-line-using-fgets > parse-line-with-sscanf From my experience, just about *any* application would be programmed better using "fgets" and "sscanf" instead of "scanf".... > By the way, don't use gets(); your input buffer can be > overrun if an input line is very long, resulting in > unpredictable malfunctioning of your application. When > you use fgets(), it is often wise to test the last > character in the record and if it is a newline, replace > it with a 0 string terminator before parsing the record. And if it is NOT a newline, yell, scream, and bitch that somebody gave you a line which was too long; otherwise, your program will think that the rest of the line (i.e., everything after the cutoff) is an additional line. The SCCS "delta" command, when reading the output from "bdiff", didn't do this, and got HORRIBLY confused if the new version of the file had a line longer than about 510 characters long. -- Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.arpa (yes, really)
gwyn@BRL.ARPA (VLD/VMB) (04/07/86)
Good point about treating non-newline fgets() data as an error; besides a line too long, this might also result from the user sending a delimiter such as EOT from a terminal. (The SVID says this, but SVR2 doesn't seem to act that way.)
rbj@icst-cmr (Root Boy Jim) (04/09/86)
yoda@ittatc.ATC.ITT.UUCP (Todd C. Williams [Jedi Knight]) writes: >Is it possible to use gets() after scanf() ? >Is it a good idea to try to use gets() after scanf() ? >It doesn't work, so I tried adding "fflush(stdin);" >just before the gets(), but that doesn't help either. >If I do 2 "gets(str)"'s in a row, the second one works. > >Apparently, the scanf() is reading UP TO the newline, but >leaving that newline in the buffer; the gets() sees the >newline and thinks it is finished. So what's the problem? Use gets after scanf to eat the \n. Doug Gwyn replys: scanf() does whatever you tell it to with the input stream then stops. If you make it eat newlines, it will. There should be no problem mixing any of the STDIO input methods. However, it sounds to me like your application would be programmed better with the following scheme: while get-a-line-using-fgets parse-line-with-sscanf The way I understand it, scanf will eat input only as far as makes sense, ungetc'ing the rest. The problem with sscanf is that if your input only partially matches, there is no way to tell where `the rest' begins. Or am I in outer space? By the way, don't use gets(); your input buffer can be overrun if an input line is very long, resulting in unpredictable malfunctioning of your application. When Agreed. Gets is `obseleted' by fgets. you use fgets(), it is often wise to test the last character in the record and if it is a newline, replace it with a 0 string terminator before parsing the record. Which brings me to another point. Fgets is worthless on binary data. It returns its first argument, which I already know. If a null is part of the data, how do you know where it stopped reading. Well if you're lucky, there will be a newline in there and that's the end of it. But if you're reading blocks of nulls, you're SOL. I would like fgets to return the number of chars read. (Root Boy) Jim Cottrell <rbj@cmr> Baseball in D.C. in `87!
gwyn@BRL.ARPA (VLD/VMB) (04/09/86)
For reading binary data, don't use fgets(), which is designed for text streams. Use fread() instead.
jsdy@hadron.UUCP (Joseph S. D. Yao) (04/10/86)
In article <2476@brl-smoke.ARPA> rbj@icst-cmr (Root Boy Jim) writes: >Which brings me to another point. Fgets is worthless on binary >data. It returns its first argument, which I already know. > ... I would like fgets to return the number of chars read. T h a t is what fread() is for. Use it. Having an element-size and a number-of-elements is useful when doing, e.g., structure I/O, otherwise it is a bit of a pain, I'll agree. [BTW, we have some decent pinball machines down at this end of Montgomery County, tho I can't recall seeing Big Injun.] -- Joe Yao hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP}
kwh@bentley.UUCP (KW Heuer) (04/10/86)
In article <2476@brl-smoke.ARPA> rbj@icst-cmr (Root Boy Jim) writes: >The problem with sscanf is that if your input only partially matches, >there is no way to tell where [the next input character is]. Agreed. I'm somewhat surprised this isn't listed under "BUGS". Of course, in many applications you don't care (just output "syntax error" and toss the line away); and it may be feasible to re-parse the entire line with a new format in any case. >Fgets is worthless on binary data. It returns its first argument, which I >already know. If a null is part of the data, how do you know where it >stopped reading. Well if you're lucky, there will be a newline in there >and that's the end of it. But if you're reading blocks of nulls, you're >SOL. I would like fgets to return the number of chars read. Clearly fgets isn't intended for binary data. (Who writes line-oriented binary data??) Probably fread is what you want. However, I think you're right that nchars is a more useful return value (though I'd be satisfied with a boolean). Karl W. Z. Heuer (ihnp4!bentley!kwh), The Walking Lint
rbj@icst-cmr (root) (04/11/86)
> In article <2476@brl-smoke.ARPA> rbj@icst-cmr (Root Boy Jim) writes: > >Fgets is worthless on binary data. It returns its first argument, which I > >already know. If a null is part of the data, how do you know where it > >stopped reading? Well if you're lucky, there will be a newline in there > >and that's the end of it. But if you're reading blocks of nulls, you're > >SOL. I would like fgets to return the number of chars read. > > Clearly fgets isn't intended for binary data. (Who writes line-oriented > binary data??) Probably fread is what you want. However, I think you're > right that nchars is a more useful return value (though I'd be satisfied > with a boolean). > > Karl W. Z. Heuer (ihnp4!bentley!kwh), The Walking Lint Allow me to clarify my position. I came across this while writing an SMTP implementation. Most of what you see is text, altho ANY char may be escaped with a backslash. It would have been easy enuf to look for a '\n' that was not escaped and pass back the entire line. Even with ascii data, I often find I want the count more often than I want the first argument, which I already know. Perhaps it's designers didn't know what to return, so they just punted & returned the first argument because so many other stdio funxions did. This is regrettable, because fgets has the char count right at hand. (Root Boy) Jim Cottrell <rbj@cmr>