Reputation: 33
If I'm not wrong, library function int fscanf(FILE *stream, const char *format, ...)
works
exactly the same as function int scanf(const char *format, ...)
except that it requires stream selection.
For example if I wanted to read two int
s from standard input the code would look something like this.
int first_number;
int second_number;
scanf("%d%d", &first_number, &second_number);
There's no point of me adding newline character in between format specifiers even though the second number is entered in next line of input? Function just looks for next decimal integer right? What happens when I enter two characters instead of int
s? Why the function sometimes doesn't work if there's a space between format specifiers?
In addition to that. When reading from file with fscanf(..)
, lets says the txt file contains next lines:
P6
255
1920 1080
Do I need to specify next line characters in fscanf(..)
? I read it like this.
FILE *input = ..
char type[2];
int tr;
int width; int height;
fscanf(input, "%s\n", &type);
fscanf(input, "%d\n" &tr);
fscanf(input, "%d %d\n", &width, &height)
Is there a need for \n
to signal next line?
Can fscanf(..)
anyhow affect any other functions for reading files like fread()
? Or is it a good practice to just stick to one function through the whole file?
Upvotes: 1
Views: 403
Reputation: 123458
The %d
conversion specifier tells scanf
and fscanf
to skip over any leading whitespace, then read up to the first non-digit character, so you don’t need to put a newline between the two %d
in the scanf
call - in fact, if you do that, it means you have to have a newline between your inputs, not just blanks.
Most conversion specifiers skip over leading whitespace - the only ones that don’t are %c
and %[
, so you’ll want to be careful when using them.
Upvotes: 1
Reputation: 153338
scanf(...)
operates like fscanf(stdin, ....)
.
Unless '\n'
, ' '
, or other white spaces are inside a "%[...]"
, as part of a format for *scanf()
, scanning functions the same as if ' '
, '\t'
'\n'
was used. (Also for '\v
, '\r
, '\f
.)
// All function the same.
fscanf(input, "%d\n" &tr);
fscanf(input, "%d " &tr);
fscanf(input, "%d\t" &tr);
There's no point of me adding newline character in between format specifiers even though the second number is entered in next line of input?
All format specifiers except "%n"
, "^[...]"
, "%c"
consume optional leading white-spaces. With "%d"
the is no need other than style to code a leading white-space in the format.
Function just looks for next decimal integer right?
Simply: yes.
What happens when I enter two characters instead of ints?
Scanning stops. The first non-numeric input remains in stdin
as well as any following input. The *scanf()
return value reflects the incomplete scan.
Why the function sometimes doesn't work if there's a space between format specifiers?
Need example. Having spaces between specifiers is not an issue unless the following specifier is one of "%n"
, "^[...]"
, "%c"
.
When reading from file with
fscanf(..)
, .... Do I need to specify next line characters in fscanf(..)?
No. fscanf()
is not line orientated. Use fgets()
to read lines. fscanf()
is challenging to use to read a line. Something like
char buf[100];
int cnt = fscanf(f, "%99[^\n]", buf);
if (cnt == 0) {
buf[0] = 0;
}
if (cnt != EOF) {
cnt = fscanf(f, "%*1[^\n]");
}
I read it like this. ...
fscanf(input, "%s\n", &type); fscanf(input, "%d\n" &tr);
....
"it" as in a line is not read properly as "%s"
, "%d"
, "\n"
all read consume 0, 1, 2, ... '\n'
and other white-spaces. They do not read a line nor just the 1 character of the format.
Further "\n"
does not complete upon reading 1 '\n'
, but continues reading all white-spaces until a non-white-space is detected (or end-of-file). Do not append such to the end of a format to read the rest of the line.
If want to read the trailing '\n'
, code could use int cnt = fscanf(input, "%d%*1[\n]" &tr);
, but code will not know if it succeeded in reading the trailing '\n'
after the int
. It will have simply read it if it was there. Could use other formats, but really, using fgets()
to read a line is better.
Is there a need for \n to signal next line?
No, as a format "\n"
reads 0 or more whites-spaces, not just new-lines.
Can fscanf(..) anyhow affect any other functions for reading files like fread()?
Yes. All input function affect what is available next for other input functions. Mixing fread()
and fscanf()
is challenging to get right.
is it a good practice to just stick to one function through the whole file?
It certainly is simpler. I recommend to use input functions as building blocks for a helper function to handle your file input.
Tip: Read lines with fgets()
, then parse. Set fscanf()
aside until you understand why it has so much trouble with unexpected input.
Upvotes: 2