473,405 Members | 2,310 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Do input functions use fgetc inside them or read()

Do the "larger" input functions like scanf, gets, fgets use fgetc to
take input or an operating system call function like read() (I know it
could be any "way", but I'm trying to find out how it's best to "think
of it")?

I've seen some explain it as if they call fgetc internally, then I've
seen some people explain it as if they call some lower level OS system
call like read(). I've even seen some older posts talk about a input
functions interacting directly with drivers (tty comes up a lot).

I've been searching through the deja/google archives and there is a
mixture of "ways of thinking how larger input functions operate." This
is important to figure out little nook and crany issues like the
eof/error post recently that made me more confused than I've ever been
before about input. This is a sticking point in my journey to
understand these topics on my own- so pls try not to give me RTFM
answers :-). I also understand many things I'm talking about are not
part of the C standard, but they are interfaces to the C standard and
many C gurus have brought these topics up in previous posts because I
think it helps understand these standard input functions.

Side note: So far this is how I picture the things in my head.

scanf/gets
|
|
\ /
fgetc
|
|
\ /
read() (system call)
|
|
\ /
driver (like tty)

Nov 14 '05 #1
6 2254
Kobu wrote:
Do the "larger" input functions like scanf, gets, fgets use fgetc to
take input or an operating system call function like read() (I know it
could be any "way", but I'm trying to find out how it's best to "think
of it")?
They obtain their input "as if" by calling fgetc(). This
does not imply that there's an actual fgetc() or getc() call
in the implementation of fread(), say, but the net observable
effect must be the same.
I've seen some explain it as if they call fgetc internally, then I've
seen some people explain it as if they call some lower level OS system
call like read(). I've even seen some older posts talk about a input
functions interacting directly with drivers (tty comes up a lot).
Different implementations ... well, they differ: that's
why we call them "different!" Some use read(), some use mmap(),
some use SYS$GET(), some use Black Magic. The C Standard says
what the implementation must do, not how it is to be done.
Side note: So far this is how I picture the things in my head.

scanf/gets
|
|
\ /
fgetc
|
|
\ /
read() (system call)
|
|
\ /
driver (like tty)


This is a plausible schematic, but by no means universal.
The crucial question is this: Why do you need to know what
happens "under the hood?" Thirst for knowledge? Fine: just
realize that the knowledge you gain about one implementation
may not be transferable to the next. Performance? Fine:
just realize that the trick that makes machine A read input
ten times faster causes machine B imitate molasses flowing
uphill in winter. A desire to mix-and-match the "lower-level"
and "upper-level" calls? Fine again: just realize that the
technique that does wonders on machine A causes machine B to
blue-screen ...

When you have the luxury (and it *is* a luxury) of
treating your libraries as "black boxes" and simply letting
them "do their own thing," by all means do so: You save an
enormous amount of pain. Do not attempt to outwit those
libraries unless the amount of pain you already suffer from
exceeds the amount you will incur.

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 14 '05 #2
Eric Sosman <es*****@acm-dot-org.invalid> writes:
[...]
Performance? Fine:
just realize that the trick that makes machine A read input
ten times faster causes machine B imitate molasses flowing
uphill in winter.

[...]

<OT>
Not everything is as it seems. Google "Boston molasses disaster" for
a counterexample to your implicit assumption.
</OT>

Followups redirected appropriately.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #3
"Kobu" <ko********@gmail.com> wrote in message
news:11**********************@l41g2000cwc.googlegr oups.com...
Do the "larger" input functions like scanf, gets, fgets use fgetc to
take input or an operating system call function like read() (I know it
could be any "way", but I'm trying to find out how it's best to "think
of it")?

I've seen some explain it as if they call fgetc internally, then I've
seen some people explain it as if they call some lower level OS system
call like read().
Explaining it as the more complex functions calling the simpler ones if the
goal is to explain how they all work together without the details of where
the character stream(s) comes from (or go to, in the case of output). It's
possible a really naive implementation might do that, but it's not the most
efficient method.

The way I'd explain it comes in two layers; there's a "lower" layer that
fetches a bunch of characters from the OS and stores them in a hidden array
(probably in the FILE object) plus an "upper" layer that studies the array,
removes however many characters are needed, and delivers them to your
program. If the array doesn't have enough content to meet your needs, the
upper layer calls into the lower layer to go get more. The upper layer, of
course, consists of the user-visible functions like fgetc() and scanf().
The lower level would be some implementation-specific wrappers around OS
functions/syscalls, e.g. read(). Reverse the process for output streams.

That's a long way of saying that scanf() doesn't call fgetc() but rather
both of them use a common facility which is invisible to you. Of course,
any particular implementation might be written differently; my concept might
be horribly inefficient compared the magic that systems implementors cook
up.
I've even seen some older posts talk about a input
functions interacting directly with drivers (tty comes up a lot).


This may be the case for DOS and embedded systems, but it'd never fly in a
multitasking environment like UNIX or Windows. It's probably not even true
on DOS since it'd prevent shell redirection and other handy tricks.

If my explanation made sense, I'd suggest you grab the source for glibc and
look at how the GNU folks do it...

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Aaron Sorkin

Nov 14 '05 #4
"Eric Sosman" <es*****@acm-dot-org.invalid> wrote in message
news:ar********************@comcast.com...
The crucial question is this: Why do you need to know what
happens "under the hood?" Thirst for knowledge? Fine: just
realize that the knowledge you gain about one implementation
may not be transferable to the next.
And it may not need to be; some people understand abstraction layers more
easily by looking at how things work under the hood in one implementation
even if they never actually take advantage of those details in their own
code.
When you have the luxury (and it *is* a luxury) of
treating your libraries as "black boxes" and simply letting
them "do their own thing," by all means do so: You save an
enormous amount of pain. Do not attempt to outwit those
libraries unless the amount of pain you already suffer from
exceeds the amount you will incur.


Of course. OTOH, learning how the Standard Library interfaces with your
implementation is a great tool in learning how to interface with other parts
of your implementation the Standard doesn't cover. Hopefully in the process
one will learn to create a layer of abstration that will allow the
unportable parts of one's code to be segregated for easier porting in the
future.

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Aaron Sorkin

Nov 14 '05 #5
In <11**********************@l41g2000cwc.googlegroups .com> "Kobu" <ko********@gmail.com> writes:
Do the "larger" input functions like scanf, gets, fgets use fgetc to
take input or an operating system call function like read() (I know it
could be any "way", but I'm trying to find out how it's best to "think
of it")?


<stdio.h> streams are typically buffered. So, all input functions look
for input into the stream buffer. If this buffer is empty, the
implementation has to refill it, by asking the OS to read more data
from the (physical or logical) device to which the stream is connected
and to store it into the stream buffer. It is obvious that this is
achieved in a highly OS-specific way.

Fortunately, all you need to know is that "larger" input functions
behave *as if* they obtained the data through repeated fgetc() calls.

Dan
--
Dan Pop <Da*****@ifh.de>
Nov 14 '05 #6
"Kobu" <ko********@gmail.com> writes:
Do the "larger" input functions like scanf, gets, fgets use fgetc to
take input or an operating system call function like read() (I know itcould be any "way", but I'm trying to find out how it's best to "thinkof it")?


Thank you all for your comments. The reason I wanted to know a little
bit about what's happening below the input functions is because it
gives me enlightenment into how the upper parts work, and also shows me
where the boundary is (so i can be more careful about segregating the
too). I've run into problems between different implementations, and
this is a sample of the problem.

The following code was testing on a *n*x/bsd type system and then a
winconsole/dos type system. The behaviour is totally different... for
the carefully picked input that I chose which should force the *under
the hood* fgetc to act the same on both systems (both systems also have
NON STICKY EOF when dealing with interactive terminal).

#include <stdio.h>

int main()
{
char string1[30];
char string2[30];

scanf("%s", string1);
scanf("%s", string2);

if (!*string1)
printf("string1 IS nul terminated\n");
else
printf("string1 not nul terminated\n");

if (!*string2)
printf("string2 IS nul terminated\n");
else
printf("string2 not nul terminated\n");

return 0;
}
On the *n*x system, I gave it two EOF signals (Ctrl+D), the program
ended.

On the win system, I had to give it four EOF signals (Ctrl+Z, Enter),
then only did the program end (2 signals per scanf).

Based on the responses to my original post, I am safe to assume that
scanf gets input "as if" by fgetc. If I assume that, fgetc should flag
scanf with a value equal to the EOF macro, and scanf should get the
hint and return (not wait for another fgetc-EOF like my win system is
doing).

Based on the fgetc theory, how can one explain the win system. This is
precisely why I asked if it was safe for me to assume fgetc under the
hood of scanf and larger functions or whether I have to go a layer up,
or down to find the boundary between the STANDARD and NON STANDARD.

Some help please.

[BTW, according to both implementations, fgetc should return EOF in
each case - Ctrl+D on beginning of line for *n*x OR Ctrl+Z & Enter at
beginning of line for Win system. Thus there is no difference at the
fgetc-EOF layer as far as my experiment goes, so where *can* the
difference be? ]

Nov 14 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Alex Vinokur | last post by:
Copying files : input to output =============================== C/C++ Performance Tests ======================= Using C/C++ Program Perfometer http://sourceforge.net/projects/cpp-perfometer...
2
by: der | last post by:
Hello all, I want to use fgets() to read lines. Now, if the user has entered more characters than it was supposed to, the next call to fgets() would read these characters, which I don't want to...
9
by: Mikhail Teterin | last post by:
Hello! I'd like to have a variable of a pointer-to-function type. The two possible values are of type (*)(FILE *) and (*)(void *). For example: getter = straight ? fgetc : gzgetc; nextchar...
3
by: Fao, Sean | last post by:
Hello all, As stated in another message, it's been a long time since I've done any C coding and I'm not feeling comfortable that I'm doing this correctly. Basically, I'd like to verify that my...
3
by: cinsky | last post by:
Hi, While reading ISO C Standard, I found follow text in 7.19.8.1: size_t fread(void *restrict ptr, size_t SIZE, ...) ... For each object, SIZE calls are made to the fgetc function and the...
1
by: pxllyte | last post by:
The input file data size is unknown so I would have to use malloc( ) to allocate enough memory for the file data. In order to do this, I would need to read each character of the file possibly by...
31
by: Francine.Neary | last post by:
One interesting thing to come out of the recent "Alignment" thread is that it is impossible to write a portable replacement for malloc in "user space" (not sure what the right term is - I mean an...
8
by: psy_berpunk | last post by:
hey, i'm trying to write a simple program to read gif87a non- interlaced format with a single image-descriptor --- I am using djgpp on windows xp. Sounds simple enough, unfortunatly data in...
14
by: n3o | last post by:
Hello Comp.Lang.C Members, I have an issue with user input that I have been trying to figure out for the longest. For instance, let's say you have something like this: void foo() { int num;...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.