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

question abt fscanf

P: n/a
Hi All,

here is one code:
int main() {
FILE*fp;
unsigned long a;
fp = fopen("my_file.txt","w+");
a = 24;
fprintf(fp,"%ld",a);
while(fscanf(fp,"%ld",&a) == 1) {
printf("%ld",a);
count++;
}
printf("count = %ld",count);
return(0);
}

I belive tht data in file is stored as ascii character constants i.e
'2' & '4'.
When data is retrived back with fscanf,does it read character by
character i.e 1 char in one iteration or it reads 2 characters at once
due to "%ld"?
well does %d,%c,%ld make any difference in retriving data with fscanf
or does fscanf read data char by char?
Do these format specifiers perform an ascii to binary conversion
before storing data in dest variable?
pls help.
Thanks
-Siliconwafer

Nov 15 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a
In article <11**********************@f14g2000cwb.googlegroups .com>
siliconwafer <sp*********@yahoo.com> wrote:
here is one code:
int main() {
FILE*fp;
unsigned long a;
fp = fopen("my_file.txt","w+");
a = 24;
fprintf(fp,"%ld",a);
This code is already broken: what if fopen() returns null?
while(fscanf(fp,"%ld",&a) == 1) {
As of this line, this code is now *severely* broken. Even if
the fopen() succeeds, the first operation done (a printf) puts
the file in "write mode". Standard C makes requirements on
the programmer before taking a "write mode" file (opened for
r+, w+, or a+ but put into write mode) and using it for "read
mode". In general, you should do a file-seeking operation
first, such as:

result = fseek(fp, 0L, SEEK_CUR);

At least this code tests the result of the scanf() call, though! :-)
printf("%ld",a);
count++;
}
printf("count = %ld",count);
return(0);
}

I belive tht data in file is stored as ascii character constants i.e
'2' & '4'.
Maybe; maybe not. Since the argument to fopen() was "w+", the file
is emptied of any previous contents and is manipulated as a text
file (rather than a binary file). Whether the text is ASCII depends
on other factors -- an IBM mainframe, for instance, would typically
use EBCDIC instead.
When data is retrived back with fscanf,does it read character by
character i.e 1 char in one iteration or it reads 2 characters at once
due to "%ld"?
This question reveals some basic misunderstandings.

All file I/O is defined in terms of fgetc() and fputc(), i.e., one
character at a time. However, the scanf() family of functions
(scanf, fscanf, sscanf, and in C99 the vscanf etc variants) use
what I like to call a "scanf engine" to read and interpret input.
The scanf engine obeys the directives given in the format string.
Format directives include percent-prefixed conversions, like %c
and %d, and also literal characters and whitespace.

The %ld directive consists of three parts: the '%' sign that
introduces a conversion, the 'l' modifier, and the 'd' conversion
directive. The 'l' modifier tells the scanf engine to read
and convert a "long int" rather than a plain int, in this case.

The conversion itself begins by reading and consuming as much
white space as possible, with the logical equivalent of:

int c;
do {
c = fgetc(fp);
} while (isspace(c));

Note that this skips leading blanks, tabs, newlines, backspaces,
form-feeds, and vertical-tabs. It will read straight through six
million blank lines if necessary, all without any sort of warning
or hint that it is doing so.

Having finished the above loop (or some other equivalent code),
the "%d" directive continues to read and consume characters until
it gets a non-sign and non-digit character:

if (c == '-' || c == '+') {
... remember the sign as neeeded ...
c = fgetc(fp);
}
while (isdigit(c)) {
... accumulate the value to convert ...
c = fgetc(fp);
}

The loop here terminates only when c is not a digit; at this point,
either c is a non-digit character, or c==EOF. If c is not equal to
EOF, the scanf engine has to put it back into the stream, as if
via ungetc() but without disturbing the ability for the user to
do his own ungetc() call:

if (c != EOF)
internal_ungetc(c, fp);

Except for this "special version of ungetc", you can write fscanf()
yourself in portable ANSI C. The main reasons to use the implementor's
version (such as the one I provided for the various BSDs) is that
(a) the implementor already did the work, and (b) he may have taken
advantage of the implementation to make the code more efficient
than straight fgetc() calls.

Finally, %d (or %ld in this case) will, if assignment was not
suppressed via "%*", store the result of a conversion -- done mostly
as if via strtol(), but with undefined behavior if the result does
not fit -- through the pointer that the caller must have supplied
as the appropriate variable argument:

*(va_arg(ap, long *)) = strtol(accumulated_value, NULL, 10);
well does %d,%c,%ld make any difference in retriving data with fscanf
or does fscanf read data char by char?
This question seems to imply that these are contradictory options.
They are not. The conversions make a great deal of difference,
but fscanf must always act "as if" it read the data one "char" at
a time. However, the "%c" conversion *does not* skip leading
whitespace:

if (conversion == 'c' || conversion == '[')
c = fgetc(fp); /* do not skip white space */
else {
/* do skip leading whitespace */
do {
c = fgetc(fp);
} while (isspace(c));
}
if (c == EOF)
... handle input failure ...
/* now c is the first character of the field */
switch (conversion) {
... handle %c, %d, %o, %s, %[, etc conversions ...
}
Do these format specifiers perform an ascii to binary conversion
before storing data in dest variable?


Again, ASCII is not required, but "%d" conversions behave similarly
to atoi(), atol(), strtol(), and so on.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 15 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.