Claude Yih wrote:
M. Åhman wrote:
<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()."
...
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.
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
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
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
pointer to the stream's buffer; _r a count of characters remaining in
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
function calling overhead:
#define getc(fp) __sgetc(fp)
On the other hand, in the same implementation, fread will transfer the
data from the stdio buffer to your specified buffer using memcpy, which
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 = count * size) == 0)
return (0);
p = buf;
while (resid > (r = fp->_r)) {
(void)memcpy((void *)p, (void *)fp->_p, (size_t)r);
--
Diomidis Spinellis
Code Quality: The Open Source Perspective (Addison-Wesley 2006)
http://www.spinellis.gr/codequality