Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

fread returns more than i want

3 views
Skip to first unread message

Franz Jeitler

unread,
Dec 4, 2005, 3:32:39 PM12/4/05
to
Hello,

I have some problems with fread.. first, let's see a part of the source
file:

FILE *fp;
char buf[512];
size_t nread;
.
.
while( nread = fread(buf,1,sizeof(buf),fp) )
fwrite(buf,1,nread,stdout);

The code above is working fine, it returns a desired file on the screen.

Now the problem:
------------------
For a file server I need to give back a structure like: <
strcpy(result.text, buf) >;

For easier understanding, temporary I can also write:
< fprintf(stdout, buf) > instead of < fwrite(buf,1,nread,stdout) >.

But now at the end of each part of the file I get some strange characters
and the last block continues again
with the first lines of the file.

So, why does this happen and how can I solve the problem?

Thank's

Franz


Ulrich Eckhardt

unread,
Dec 4, 2005, 3:35:50 PM12/4/05
to
Franz Jeitler wrote:
> For easier understanding, temporary I can also write:
> < fprintf(stdout, buf) > instead of < fwrite(buf,1,nread,stdout)

No. fprintf() takes a zero-terminated string, while fwrite takes a buffer
of raw bytes. Further, fprintf() also looks at the string and interprets
it, which might not be the right thing.

Uli

Bjørn Augestad

unread,
Dec 4, 2005, 3:40:08 PM12/4/05
to
Franz Jeitler wrote:
> Hello,
>
> I have some problems with fread.. first, let's see a part of the source
> file:
>
> FILE *fp;
> char buf[512];
> size_t nread;
> ..
> ..

> while( nread = fread(buf,1,sizeof(buf),fp) )
> fwrite(buf,1,nread,stdout);
>
> The code above is working fine, it returns a desired file on the screen.
>
> Now the problem:
> ------------------
> For a file server I need to give back a structure like: <
> strcpy(result.text, buf) >;
>
> For easier understanding, temporary I can also write:
> < fprintf(stdout, buf) > instead of < fwrite(buf,1,nread,stdout) >.
>
> But now at the end of each part of the file I get some strange characters
> and the last block continues again
> with the first lines of the file.
>
> So, why does this happen and how can I solve the problem?

I'm guessing here, as you didn't provide a complete program. fread()
does not terminate the buffer with a string terminator, so when you
strcpy() of fprintf(), you copy/write more characters than expected.

BTW, fprintf(stdout, buf) is a really bad idea,
fprintf(stdout, "%s", buf) is much better.


HTH
Bjørn

Eric Sosman

unread,
Dec 4, 2005, 3:44:59 PM12/4/05
to
Franz Jeitler wrote:
> [...]

> For a file server I need to give back a structure like: <
> strcpy(result.text, buf) >;
>
> For easier understanding, temporary I can also write:
> < fprintf(stdout, buf) > instead of < fwrite(buf,1,nread,stdout) >.
>
> But now at the end of each part of the file I get some strange characters
> and the last block continues again
> with the first lines of the file.
>
> So, why does this happen and how can I solve the problem?

You get a different interpretation if you regard buf as
a zero-terminated string than if you regard it as an array
of nread characters. In particular, if buf lacks a zero
terminator it is not a proper string, and passing it to
fprintf() invokes undefined behavior. (A likely result is
that fprintf() will "run off the end" of buf until it stumbles
upon a zero byte somewhere else in memory; you are probably
seeing the characters that precede that zero.)

Also, if '%' appears anywhere in buf, fprintf() will try
to interpret it as a formatting directive ...

Your best bet is to use fwrite(), as you apparently intend
to do eventually in any case.

--
Eric Sosman
eso...@acm-dot-org.invalid

Franz Jeitler

unread,
Dec 4, 2005, 4:03:14 PM12/4/05
to

"Ulrich Eckhardt" <doom...@knuut.de> schrieb im Newsbeitrag
news:3vh2etF...@uni-berlin.de...

OK, I understand, so should I terminate the string manually (even if I
return a binary char-Array
in < result.text> ?

Franz


Franz Jeitler

unread,
Dec 4, 2005, 4:05:23 PM12/4/05
to

"Eric Sosman" <eso...@acm-dot-org.invalid> schrieb im Newsbeitrag
news:2tSdnc4_jIL...@comcast.com...

> Your best bet is to use fwrite(), as you apparently intend
> to do eventually in any case.
>
> --
> Eric Sosman
> eso...@acm-dot-org.invalid


Sorry, but I have to write the block into a structure for returning it to a
client, so what do you suggest?

Franz


Ulrich Eckhardt

unread,
Dec 4, 2005, 4:08:04 PM12/4/05
to
Franz Jeitler wrote:
> "Ulrich Eckhardt" <doom...@knuut.de> schrieb im Newsbeitrag
> news:3vh2etF...@uni-berlin.de...
>> Franz Jeitler wrote:
>>> For easier understanding, temporary I can also write:
>>> < fprintf(stdout, buf) > instead of < fwrite(buf,1,nread,stdout)
>>
>> No. fprintf() takes a zero-terminated string, while fwrite takes a
>> buffer of raw bytes. Further, fprintf() also looks at the string
>> and interprets it, which might not be the right thing.
>
> OK, I understand, so should I terminate the string manually (even if I
> return a binary char-Array
> in < result.text> ?

No, use the right functions for whatever you are doing. If you have a
buffer containing text, that text will usually be followed by a null
character, if there isn't one, you might add it. If your buffer contains
other data, it might be perfectly possible that there is a null character
in the middle - functions only reading a buffer up to the first null char
are then not the suitable tool to handle such data.

Uli


Eric Sosman

unread,
Dec 4, 2005, 4:15:26 PM12/4/05
to

What does the client expect to receive from you? If
the struct contains the bytes, like this:

struct {
size_t count;
char bytes[512];
} client_data;

... then you can just read the data directly into the
struct, like this:

client_data.count = fread(client_data.buf, 1,
sizeof client_data.buf, fp);

--
Eric Sosman
eso...@acm-dot-org.invalid

Franz Jeitler

unread,
Dec 4, 2005, 4:24:29 PM12/4/05
to

"Eric Sosman" <eso...@acm-dot-org.invalid> schrieb im Newsbeitrag
news:kJGdnYmdhtT...@comcast.com...

> char bytes[512];
> } client_data;
>
> ... then you can just read the data directly into the
> struct, like this:
>
> client_data.count = fread(client_data.buf, 1,
> sizeof client_data.buf, fp);
>
> --
> Eric Sosman
> eso...@acm-dot-org.invalid

Oh yes, I think that might work, because my client code has < printf ("%s",
result.text) instead of < fread...>.

Thank you

Franz Jeitler


Eric Sosman

unread,
Dec 4, 2005, 5:18:31 PM12/4/05
to

Aha! The client expects you to supply a zero-terminated
string, not a counted array of bytes. You should be using a
string-oriented input function like fgets(), not the array-
oriented fread().

--
Eric Sosman
eso...@acm-dot-org.invalid

0 new messages