By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,948 Members | 664 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,948 IT Pros & Developers. It's quick & easy.

fgetc() vs. fread()

P: n/a
I'm reading "C: A Reference Manual" but still can't understand a
very basic thing: is there any functional difference between
fgetc/fputc and fread/fwrite (when reading/writing one unsigned
char)?

1. Books and documentation on C tell me fread and fwrite is "binary".
What does binary mean in this? Anything to do with opening a file
in binary mode?

2. I'm also sure I've read somewhere on the net that fread and
fwrite are unbuffered. True or false?

3. I found this when googling:

[ Lawrence Kirby @ comp.lang.c, Sat 5 Feb 2000 ]
....
"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()."
....

If that's true, I think it would answer the first 2 questions.

Magnus
Apr 12 '06 #1
Share this Question
Share on Google+
8 Replies


P: n/a
In article <20***************************@cyberspace.org>,
M. =?ISO-8859-1?Q?=C5hman?= <ah***@cyberspace.org> wrote:
2. I'm also sure I've read somewhere on the net that fread and
fwrite are unbuffered. True or false?


More false than true. Buffering is a (modifiable) property of the
stream, and applies no matter which of the standard I/O functions
are used to access it.

Possibly what you were looking at was an item about read() and
write() instead of fread() and fwrite(). read() and write() are
very commonly implemented (e.g., Unix, POSIX), but are not part of
the standard C library [and are relatively unlikely ever to
adopted into C itself.]
--
Prototypes are supertypes of their clones. -- maplesoft
Apr 12 '06 #2

P: n/a
M. ┼hman wrote:
I'm reading "C: A Reference Manual" but still can't understand a
very basic thing: is there any functional difference between
fgetc/fputc and fread/fwrite (when reading/writing one unsigned
char)?

1. Books and documentation on C tell me fread and fwrite is "binary".
What does binary mean in this? Anything to do with opening a file
in binary mode?


On systems (like Microsoft Windows) that have different conventions for
text and "binary" files opening a file in binary mode will affect both
fread/fwrite and fgetc/fputc. The expalanation for what you've read is
that the fread/fwrite interface is more suited for processing files
containing binary data, whereas the getc/putc interface is more suited
for processing text files.

For example, the Unix dump command reads user data records from the
(binary-structured) utmp file directly into the corresponding utmp
struct using the following fread call:

struct utmp utmp;
if (fread((char *) &utmp, sizeof (struct utmp), 1, f_utmp) != 1)

while the Unix cat command removes successive newlines from
(text-structured) files using the following getc call:

for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
if (prev == '\n') {
if (ch == '\n') {

Nothing prevents you from processing text files with fread/fwrite (for
example by reading chunks into a large buffer) or binary files with
getc/putc (for example by assembling the data into variables by
hand-crafted code).

--
Diomidis Spinellis
Code Quality: The Open Source Perspective (Addison-Wesley 2006)
http://www.spinellis.gr/codequality
Apr 12 '06 #3

P: n/a
M. ┼hman said:

<snip>
3. I found this when googling:

[ Lawrence Kirby @ comp.lang.c, Sat 5 Feb 2000 ]
...
"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()."
...

If that's true, I think it would answer the first 2 questions.


When Lawrence Kirby says something about C, you can be more sure of its
accuracy than of your ability to walk in a straight line whilst sober.

From a quick glance at your quote, it looks perfectly correct to me.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Apr 13 '06 #4

P: n/a
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?

Apr 13 '06 #5

P: n/a
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
Apr 13 '06 #6

P: n/a
On Wed, 12 Apr 2006 23:48:56 +0300, Diomidis Spinellis <dd*@aueb.gr>
wrote:
<snip>
On systems (like Microsoft Windows) that have different conventions for
text and "binary" files opening a file in binary mode will affect both
fread/fwrite and fgetc/fputc. The expalanation for what you've read is
that the fread/fwrite interface is more suited for processing files
containing binary data, whereas the getc/putc interface is more suited
for processing text files.
Exactly. (And very nicely put.)
For example, the Unix dump command reads user data records from the
(binary-structured) utmp file directly into the corresponding utmp
struct using the following fread call:

struct utmp utmp;
if (fread((char *) &utmp, sizeof (struct utmp), 1, f_utmp) != 1)
dump? Why on Earth should dump care about logins? I don't think it
even cares or cared about userids at all, and if it does or did,
/etc/passwd is not and never was fixed format.
while the Unix cat command removes successive newlines from
(text-structured) files using the following getc call:

for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
if (prev == '\n') {
if (ch == '\n') {
GNU cat does this (and several other equally silly things) but no
other Unix that I've ever heard of does.
Nothing prevents you from processing text files with fread/fwrite (for
example by reading chunks into a large buffer) or binary files with
getc/putc (for example by assembling the data into variables by
hand-crafted code).


Now that is true.

- David.Thompson1 at worldnet.att.net
May 1 '06 #7

P: n/a
In article <1i********************************@4ax.com>,
Dave Thompson <da*************@worldnet.att.net> wrote:
dump? Why on Earth should dump care about logins?


To send messages to all logged-in operators, probably.

-- Richard
May 1 '06 #8

P: n/a
On 2006-05-01, Dave Thompson <da*************@worldnet.att.net> wrote:
On Wed, 12 Apr 2006 23:48:56 +0300, Diomidis Spinellis <dd*@aueb.gr>
wrote:
<snip>
On systems (like Microsoft Windows) that have different conventions for
text and "binary" files opening a file in binary mode will affect both
fread/fwrite and fgetc/fputc. The expalanation for what you've read is
that the fread/fwrite interface is more suited for processing files
containing binary data, whereas the getc/putc interface is more suited
for processing text files.

Exactly. (And very nicely put.)
For example, the Unix dump command reads user data records from the
(binary-structured) utmp file directly into the corresponding utmp
struct using the following fread call:

struct utmp utmp;
if (fread((char *) &utmp, sizeof (struct utmp), 1, f_utmp) != 1)

dump? Why on Earth should dump care about logins? I don't think it
even cares or cared about userids at all, and if it does or did,
/etc/passwd is not and never was fixed format.
while the Unix cat command removes successive newlines from
(text-structured) files using the following getc call:

for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
if (prev == '\n') {
if (ch == '\n') {

GNU cat does this (and several other equally silly things) but no
other Unix that I've ever heard of does.


You probably haven't heard of any BSD-derived unixes, or at least
haven't heard of this feature. The -s option (to do so) is present on
AFAICT all such systems. FreeBSD's code analogous to those lines is as
follows:

for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
if (prev == '\n') {
if (sflag) {
if (ch == '\n') {

The flag check has probably been hoisted outside the loop and omitted in
the code that was pasted above.
May 1 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.