What does fscanf return when it reads data in the file. For example,
int number1, number2, number3, number4, c;
c = fscanf (spFile, "%d", &number1);
//c will be 1 in this case.
c = fscanf (spFile, "%d %d %d %d", &number1, &number1, &number3, &number4);
//in this case, c will return 4.
I just want to know why it returns such values depending on the number of arguments.
From the manpage for the Xscanf family of functions:
Upon successful completion, these functions shall return the number of
successfully matched and assigned input items; this number can be zero
in the event of an early matching failure. If the input ends before
the first matching failure or conversion, EOF shall be returned. If a
read error occurs, the error indicator for the stream is set, EOF
shall be returned, and errno shall be set to
indicate the error
So your first call to fscanf returns 1 because one input item (&number1) was successfully matched with the format specifier %d. Your second call to fscanf returns 4 because all 4 arguments were matched.
I quote from cplusplus.com .
On success, the function returns the number of items of the argument
list successfully filled. This count can match the expected number of
items or be less (even zero) due to a matching failure, a reading
error, or the reach of the end-of-file.
If a reading error happens or the end-of-file is reached while
reading, the proper indicator is set (feof or ferror). And, if either
happens before any data could be successfully read, EOF is returned.
--EDIT--
If you are intention is to determine the number of bytes read to a string.
int bytes;
char str[80];
fscanf (stdin, "%s%n",str,&bytes);
printf("Number of bytes read = %d",bytes);
From the manual page:
*These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure. *
Hence 1st one returns 1 if able to read one integer from the file, 2nd one returns 4 if able to read 4 integers from the file.
This happens to be a very straight forward question , and has been aptly answered by charles and ed before me. But they didnt mention where you should be looking for such things the next time you get stuck.
first the question --
the fscanf belongs to the family of formated input(scan) functions that are supposed to read a input and report some info on the data read like bytes or the count of items(variable addresses) that got a appropriate input read and had successfull assignment made.
here the fscanf is supposed to check for matches in the input file with the format string provided in the function call and accordingly assign the (in order of their position) variable - address with the value and once completed it will return the total count for the number of successfull assignments it made. hence the result of 1 and next was 4 (assuming input was provided properly).
second part: where to look ? --
well described details for such function are easily found in your manual pages or posix doc if you refer to one.
if you noticed , the previous two answers also contain small extracts from the man pages .
hope this helps.
The return value is not depending on the number of arguments to fscanf ,it depends on number of values successfully scanned by fscanf.
Related
So I have a .txt file that I want to read via stdin in c11 program using scanf().
The file is essentially many lines made of one single string.
example:
hello
how
are
you
How can I know when the file is finished, I tried comparing a string with a string made only with eof character but the code loops in error.
Any advice is much appreciated.
Linux manual says (RETURN section):
RETURN VALUE
On success, these functions return the number of input items
successfully matched and assigned; this can be fewer than
provided for, or even zero, in the event of an early matching
failure.
The value EOF is returned if the end of input is reached before
either the first successful conversion or a matching failure
occurs. EOF is also returned if a read error occurs, in which
case the error indicator for the stream (see ferror(3)) is set,
and errno is set to indicate the error.
So test if the return value of scanf equals to EOF.
You can read the file redirected from standard input using scanf(), one word at time, testing for successful conversion, until no more words can be read from stdin.
Here is a simple example:
#include <stdio.h>
int main() {
char word[40];
int n = 0;
while (scanf("%39s", word) == 1) {
printf("%d: %s\n", ++n, word);
}
return 0;
}
Note that you must tell scanf() the maximum number of characters to store into the destination array before the null pointer. Otherwise, any longer word present in the input stream will cause undefined behavior, a flaw attackers can try and exploit using specially crafted input.
There is more to this code obviously but I am just curious as to what this line of code actually does. I know the while loop and such but am new to the fscanf()
while (fscanf(input_file, "%s", curr_word) == 1)
fscanf() returns the number of input items successfully scanned and stored.
as per the man page
Return Value
These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.
In your case
while (fscanf(input_file, "%s", curr_word) == 1)
fsaacf() will return a value of 1 if it is able to successfully scan a string (as per the %s format specifier) from input_file and put it into curr_word.
fscanf(input_file, "%s", curr_word) reads the input stream input_file and stores the next sequence of non spacing characters into the array pointed to by cuur_word and appends a '\0' byte. As you can see, the size of this array is not passed to fscanf. This is a classical case of potential buffer overflow, a security flaw that can be exploited by a hacker by storing appropriate contents in the input stream.
After gets, the scanf family of library functions is the best source of buffer overflow bugs one can find.
It is very difficult to use fscanf correctly. Most C programmers should avoid it.
This question already has answers here:
Is `sscanf` guaranteed not to change arguments that it doesn't find?
(5 answers)
Closed 8 years ago.
If a line does not match a [fsv]scanf format, does scanf guarantee not to touch the provided pointers that are not matched?
For example, if
int int1 = 3;
int int2 = 5;
sscanf(line, "%d %d", &int1, &int2);
returns 0, are the integers guaranteed to be still 3 and 5, or can int1 have been changed?
The short answer is yes, in your case you can guarantee that int1 and int2 have not changed.
However, I would advise against relying on this behaviour, as it's likely to produce code that is difficult to read - and because:
The long answer is it depends on your format string. Looking at the C11 standard for fscanf (s7.21.6.2.16), we have:
The fscanf function returns the value of the macro EOF if an input failure occurs
before the first conversion (if any) has completed. Otherwise, the function returns the
number of input items assigned, which can be fewer than provided for, or even zero, in
the event of an early matching failure.
Critically important is this definition of input items from later in 7.21.6.2:
An input item is defined as the longest sequence of input characters which does not exceed
any specified field width and which is, or is a prefix of, a matching input sequence
So. The number returned by scanf is the number of items read from the stream, not the number of pointers written to.
Additionally relevant is 7.21.6.2.2:
If the format is exhausted while arguments remain, the excess
arguments are evaluated (as always) but are otherwise ignored.
The behaviour of ignoring arguments that aren't written to is also made explicit in an example at the end of that section:
In:
#include <stdio.h>
/* ... */
int d1, d2, n1, n2, i;
i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
the value 123 is assigned to d1 and the value 3 to n1. Because %n can never get an input failure the value of 3 is also assigned to n2. The value of d2 is not affected. The value 1 is assigned to i.
In case you're not familiar with %n, it's "the number of characters read from the stream so far".
This is a great example to illustrate your question - here we have three pointers written to, and one pointer untouched. But, fscanf only returns 1 here - because it only assigned one "input item" from the stream.
So, in your example, yes, if you've got %d %d and you pass it something which causes 0 reads, then yes, the pointers will be untouched.
But, if you've got a %n in there, then your function could still return 0 or EOF while still consuming some input and writing to pointers. For example:
sscanf("aaa","aaa%n%d",&n1,&n2);
This writes 3 to n1, leaves n2 untouched, and returns EOF. And:
sscanf("aaa bbb","aaa%n%d",&n1,&n2);
This writes 3 to n1, leaves n2 untouched, and returns 0.
There should be at least as many of these arguments as the number of values stored by the format specifier of sscanf. Additional arguments are ignored by the function sscanf.
If line contains say "10 20", then int1 and int2 will be changed to 10 and 20 respectively.
However, if line contains say "aa bb", then int1 and int2 will be retained as 3 and 5 respectively.
Note:This question is very simple but when I am searching in Google I haven't got any clear clarification.
I have following program
int main()
{
float c;
scanf("%f",&c);
printf("%f",c);
}
o/p
when I am giving a int value (e,g - 9) it is showing it as 9.000000
but when I am giving char value like 'a' it is not showing and showing 0.000000.I know the memory representation of float is totally different from int but then how when I am giving int value (9) it is showing but when I am giving char (a) which is also an int (97) is not showing.
How it is happening. What is the memory representation during char assignment.
Note that there are no chars here anywhere in your code.
This is the way scanf is supposed to work. If you check the return value from scanf (like you should be!) you'll probably see that it's returning 0, meaning no items were matched.
When you give scanf() a "%f" format string, that means "I want you to try and get me a floating point number. When you provide input like 'a', it's not going to match anything, because 'a' is not a valid floating-point number.
http://www.cplusplus.com/reference/cstdio/scanf/
First, you usually should end your printf format string with a newline \n or else call fflush.
Then, you should read the documentation on scanf i.e. its man page scanf(3)
It can fail, and it returns the number of successful matches:
Return Value
These functions return the number of input items successfully matched
and assigned, which can be fewer than provided for, or even zero in
the event of an early matching failure.
The value EOF is returned if the end of input is reached before either
the first successful conversion or a matching failure occurs. EOF is
also returned if a read error occurs, in which case the error
indicator for the stream (see ferror(3)) is set, and errno is set
indicate the error.
A failure is happening when you type an input letter a against a %f conversion specification. In your case the c variable is left unchanged (i.e. "uninitialized").
You should test the result of scanf (it is <=0 on failure in your case).
scanf in the form you wrote it will try to find and read numbers (int/float) up to the first non numerical character (newline, space, any letter). Letters are ints, but this is because of the scanf and the way it should behave. Read up the docs.
I'd like your help with understanding why this function does not stop when I enter any other number than 1.
int main(void) {
double sum,v;
while (scanf("%lf",&v)==1) {
printf("\t%.2f\n", sum += v);
}
It looks like it's suppose to stop whenever the input would be different from 1. I believe that it is has to do with the condition, maybe it checks something before what I think it does.
The function scanf returns the number of items matched and filled, not the actual value it read.
Upon successful completion, these functions shall return the number of
successfully matched and assigned input items; this number can be zero
in the event of an early matching failure. If the input ends before
the first matching failure or conversion, EOF shall be returned.
So in your code scanf will always return 1 for a successful read. You should be testing v instead (but not with ==).
scanf on success returns the number of items successfully read. Therefore you need additionally check if v == 1.