Home > Archive > Unix Programming > December 2006 > fscanf/fprintf usage
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
fscanf/fprintf usage
|
|
|
| Ok, so i want to be portable in writing out my file, and i decide to
write everything out in text. I understand that fwrite/fread can't do
text completely (what about read/write?) so i guess i go with
fprintf/fscanf.
I understand fprintf, but how, does fscanf determine the size of how
much i needs to read?
i mean, if i write a char[80] to file,and i do:
fscanf(fp,"%s",string);
How does fscanf know how much to read from file ?
i don't understand this.
Many thanks
| |
| loic-dev@gmx.net 2006-12-16, 7:06 pm |
| Hello,
> Ok, so i want to be portable in writing out my file, and i decide to
> write everything out in text. I understand that fwrite/fread can't do
> text completely (what about read/write?) so i guess i go with
> fprintf/fscanf.
>
> I understand fprintf, but how, does fscanf determine the size of how
> much i needs to read?
> i mean, if i write a char[80] to file,and i do:
>
> fscanf(fp,"%s",string);
>
> How does fscanf know how much to read from file ?
> i don't understand this.
It's very simply: it does not. fscanf(fp,"%s", string) will read as
long as it find a space ( ' ', '\t', '\n' etc.) and store the result in
string. Needless to say: this can easily lead to buffer overflow...
An alternative could be to use /fgets()/
HTH,
Loic.
| |
|
| On 2006-12-16 15:48:08 +0100, loic-dev@gmx.net said:
> Hello,
>
>
> It's very simply: it does not. fscanf(fp,"%s", string) will read as
> long as it find a space ( ' ', '\t', '\n' etc.) and store the result in
> string. Needless to say: this can easily lead to buffer overflow...
>
> An alternative could be to use /fgets()/
>
> HTH,
> Loic.
Great. So what is the normal way to do things then? I ask everyone and
everybody seems
kind of vague on the subject. Big software companies i never see
textonly files, yet everyone here
promotes textonly writes. So i step down from using fwrite/fread, and
then i get functions that can't
even determine string length or i can't pas it as an argument.
I could use fgets, but that reads a whole line. So then i'd have to
work with delimiters again.
Argh. This sucks.
| |
| Maxim Yegorushkin 2006-12-16, 7:06 pm |
|
atv wrote:
> Ok, so i want to be portable in writing out my file, and i decide to
> write everything out in text. I understand that fwrite/fread can't do
> text completely (what about read/write?) so i guess i go with
> fprintf/fscanf.
>
> I understand fprintf, but how, does fscanf determine the size of how
> much i needs to read?
> i mean, if i write a char[80] to file,and i do:
>
> fscanf(fp,"%s",string);
>
> How does fscanf know how much to read from file ?
> i don't understand this.
You either specify the maximum lenght ("%79s" in this case) or make
sure by some other means that it does not overflow your buffer.
Another simple way - use c++ IOStreams. They are somewhat easier to use
properly than fprintf/scanf for simple cases, but may be not as
flexible as sscanf, especailly when the field separator you use is not
whitespace.
| |
| Jens Thoms Toerring 2006-12-16, 7:06 pm |
| atv <alef@xs4all.nl> wrote:
> On 2006-12-16 15:48:08 +0100, loic-dev@gmx.net said:
[color=darkred]
> Great. So what is the normal way to do things then? I ask everyone and
> everybody seems kind of vague on the subject. Big software companies i
> never see textonly files, yet everyone here promaotes textonly writes.
I don't know what companies you're talking about - but there are
probably some that are only interested in writing software that
works on exactly one kind of system and aren't much interested in
making it possible to exchange data files between machines run-
ning different systems.
But if you want to avoid these restrictions then a textual
representation of the data is definitely the way to go. That
you don't get advice like "do it exactly this way" is due to
it being depend too much on what kind of data you want to store
and read back. One way to go might be something like XML, but
that involves having a parser etc. which for many simple things
would be way over the top.
> So i step down from using fwrite/fread, and then i get functions
> that can't even determine string length or i can't pas it as an
> argument.
> I could use fgets, but that reads a whole line. So then i'd have to
> work with delimiters again.
Unless the sizes of the data items are fixed or known in advance
you will always have to work with some kind of delimiter, even if
it might not be recognizable as such on a first glance.
One simple kind of "protocol", if you want to store and read back
arbitrary length strings, would be to first have a single line
(ending in a '\n') with just the lenght of the string and then
followed by the string itself. You then can use fscanf() to read
in the length and subsequently freadf() to get the string, which
length you then know and thus can alloacte enough memory for in
advance. In that case you need the '\n' as a delimiter to figure
out where the length item ends is and then you can use the know-
ledge about how long the next item is for reading it.
Or you just could use the '\0' character as an delimiter and use
e.g. fgetc(), putting what you read in into a buffer that you in-
crease in size when necessary.
But however you do it, the best way depends a lot on what exactly
you want to store and read back, how important it is to you to
catch garbled input (something which might be rather hard to when
you read in binary data) etc. There's simply no silver bullet. If
you explain your exact requirements I guess people here would very
well try to help you out with ideas how to do it. I see that you
started one of your posts with some code that wrote the contents
of a structure to a file, but since nobody than you knows what's
exactly in the structure you can't expect anybody to tell you a
good way to write it out (and what's the best way might depend
on furter constraints like smallest footprint, easiest way to
read back in, easy to catch incorrect input, readability for
humans displaying the file with 'cat' etc.).
> Argh. This sucks.
Admittedly, but there are a lot of things in live that suck and
are even harder to deal with;-)
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
| |
| Stefaan A Eeckels 2006-12-16, 7:06 pm |
| On Sat, 16 Dec 2006 17:45:37 +0100
atv <alef@xs4all.nl> wrote:
> Great. So what is the normal way to do things then? I ask everyone
> and everybody seems kind of vague on the subject.
You shouldn't ask everyone.
> Big software companies i never see textonly files, yet everyone here
> promotes textonly writes. So i step down from using fwrite/fread, and
> then i get functions that can'teven determine string length or i
> can't pas it as an argument.
How do you want a routine to recognise something without clear
conventions of what is the start and end of a string? Computers are
pretty stupid and need a lot of help. And you _can_ pass the length of
a string to scanf - only that tends to be not so useful when you're
dealing in variable length strings. There's no magic.
If you don't like what's there, write your own. One of the
immutable laws of our universe is that sooner or later every programmer
writes a bunch of routines that handle configuration files. In the
nineties, the Windows .INI format was popular:
[Section]
Item = value
These days, it's XML:
<Section>
<Item>Value</Item>
</Section>
> I could use fgets, but that reads a whole line. So then i'd have to
> work with delimiters again.
> Argh. This sucks.
Not necessarily - you can try and locate a library that handles this
for you. Time to hit Google :)
--
Stefaan A Eeckels
--
You know, it is almost always the case in the real world that something
is "fair" when you like it and "unfair" when you don't.
-- Jeffrey Siegal in gnu.misc.discuss
| |
|
| On 2006-12-16 19:13:19 +0100, "Maxim Yegorushkin"
<maxim.yegorushkin@gmail.com> said:
[color=darkred]
>
> atv wrote:
Thanks everyone. I will ponder on a solution. And possible ask a new
question here with a newly proposed solution/code.
And thanks Jens for your great answer.
Thanks!
| |
| Maxim Yegorushkin 2006-12-17, 7:04 pm |
|
Jens Thoms Toerring wrote:
[]
>
>
> Unless the sizes of the data items are fixed or known in advance
> you will always have to work with some kind of delimiter, even if
> it might not be recognizable as such on a first glance.
>
> One simple kind of "protocol", if you want to store and read back
> arbitrary length strings, would be to first have a single line
> (ending in a '\n') with just the lenght of the string and then
> followed by the string itself. You then can use fscanf() to read
> in the length and subsequently freadf() to get the string, which
> length you then know and thus can alloacte enough memory for in
> advance. In that case you need the '\n' as a delimiter to figure
> out where the length item ends is and then you can use the know-
> ledge about how long the next item is for reading it.
>
> Or you just could use the '\0' character as an delimiter and use
> e.g. fgetc(), putting what you read in into a buffer that you in-
> crease in size when necessary.
One way to simplify it a bit more is to map the text file into memory.
This way it's a simple array, no need to use any stdio functions.
|
|
|
|
|