Newsgroup: comp.lang.c


Date: Thu, 13 Apr 2006 09:41:58 +0300
From: Diomidis Spinellis <dds@aueb.gr>
Organization: Athens University of Economics and Business
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060130 SeaMonkey/1.0
MIME-Version: 1.0
Newsgroups: comp.lang.c
Subject: Re: fgetc() vs. fread()
References: <20060412182901.2bb881a6.ahman@cyberspace.org> <1144906266.197962.131730@z34g2000cwc.googlegroups.com>
In-Reply-To: <1144906266.197962.131730@z34g2000cwc.googlegroups.com>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable
Claude Yih wrote:
> M. =C5hman wrote:
>=20
> <snip>
>> ...
>> "In C a stream is a sequence of characters. All read operations are
>> defined to read data from the stream as if by one or more calls to
>> fgetc() and all write operations by one or more calls to fputc()."
>> ...
>=20
> My conception of fread and fgetc is that fgetc will bring about more
> I/O operations between memory and disk because it can only read one
> byte into memory at one time while fread reading multiple bytes.
>=20
> Is my opinion right or wrong?

The C input and output streams are typically buffered.  A large chunk is =

  read from (say) the disk into memory with one operation.  Functions=20
like getc, fgetc, fread, and fgets will pick data from that stream until =

it is empty, which will cause another transfer from the disk.  Calling=20
fgetc will incur a function call overhead, but, unless you've disabled a =

stream's buffering, certainly not the overhead of a disk operation.

Here is an example from an actual implementation of fgetc. _p is a=20
pointer to the stream's buffer; _r a count of characters remaining in=20
the buffer, and __srget a function that fills the buffer.

#define	__sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))

int
fgetc(FILE *fp)
{
         return (__sgetc(fp));
}

getc() is typically implemented as a macro, so it won't even incur the=20
function calling overhead:

#define	getc(fp)	__sgetc(fp)

On the other hand, in the same implementation, fread will transfer the=20
data from the stdio buffer to your specified buffer using memcpy, which=20
can be more efficient than byte-by-byte copies.

size_t
fread(void *buf, size_t size, count, FILE *fp)
{
         size_t resid;
         char *p;
         int r;

         if ((resid =3D count * size) =3D=3D 0)
                 return (0);
         p =3D buf;
         while (resid > (r =3D fp->_r)) {
                 (void)memcpy((void *)p, (void *)fp->_p, (size_t)r);

--=20
Diomidis Spinellis
Code Quality: The Open Source Perspective (Addison-Wesley 2006)
http://www.spinellis.gr/codequality




Newsgroup comp.lang.c contents
Newsgroup list
Diomidis Spinellis home page

Creative Commons License Unless otherwise expressly stated, all original material on this page created by Diomidis Spinellis is licensed under a Creative Commons Attribution-Share Alike 3.0 Greece License.