problem with fscanf

Sep 5, 2019 at 4:57pm
There seems to be something wrong with this:

1
2
if((fscanf(ifile, "%c", &c)) == NIL)
     abort_run("Fatal: Unable to read from ifile.\n") ;


ifile has previously opened correctly, fscanf works without triggering 'abort_run', but the value of the variable c is entirely wrong.

What needs to be changed?
Sep 5, 2019 at 5:14pm
What value is being read? What value do you actually get? What kind of object is c?
Sep 5, 2019 at 5:15pm
What is NIL? Is that a macro for 0?
If you're checking the return value of fscanf, note that it returns the number of items it was able to successfully convert, or EOF if it reaches end of file while attempting. So it would be better to check for != 1 in this case.

Can you show a minimal compilable example that reproduces your issue?

Edit: Just to show you an complete example of fscanf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    // file constains 'hello' (without the quotes)
    FILE *fp = fopen("foo.txt", "r");
    
    char ch;
    while (fscanf(fp, "%c", &ch) == 1)
    {
        printf("%c ", ch);
    }
    printf("!\n");

    return 0;
}

h e l l o !
Last edited on Sep 5, 2019 at 5:25pm
Sep 5, 2019 at 5:18pm
what is the type of c?
what is in the file, what do you *think* it should be?
its one of 2 things... you are not reading WHERE you think you are reading (where YOU think it is reading and where it IS reading mismatch), or you are not reading WHAT you think you are reading (type of data is not what you think, eg the file says 13 and you got '1' or you wanted 1 and got '1' or the like)
Last edited on Sep 5, 2019 at 5:21pm
Sep 5, 2019 at 5:24pm
What is NIL? Is that a macro for 0?
its a C (and pascal) version of null. I am not sure if there is any difference, I think its all zero in the end..

he says its getting data and not tripping the if statement so its reading something. If the stream has gone invalid, that would also explain junk data... can the stream be bad and get a nonzero read from the fscanf? I am assuming nil=null=0 etc so even if nil isnt the right thing to check (its no pointer) I think its ok (??).
Last edited on Sep 5, 2019 at 5:26pm
Sep 5, 2019 at 5:26pm
jonnin wrote:
can the stream be bad and get a nonzero read from the fscanf?
fscanf can return EOF, which is not 0.

I did't know NIL was a valid macro in C. What header is it defined in?
Last edited on Sep 5, 2019 at 5:27pm
Sep 5, 2019 at 5:27pm
ok, so add a 3rd issue: stream is dead and reading junk.
Sep 5, 2019 at 7:34pm
"NIL" is not a standard macro in C or C++.
In older or C-interfacing code, use "NULL".
In modern C++, use "nullptr".

"nil" is a valid keyword in Pascal and Object Pascal, equivalent to nullptr.

@OP, please at least get your program to compile before making factual statements about the language.
Sep 5, 2019 at 7:56pm
It also seems to be something in 'objective C' which I am not 100% sure what is.
I had to look it up, and got enough hits that it seems to be valid for some dialects.

given that the OP had it in all caps, though, it almost certainly is a local define for his code, not objective or other things. C would not use all caps for it even in an obscure dialect. I would still assume its a zero, but you may want to check it / print it / make sure.
Last edited on Sep 5, 2019 at 8:00pm
Sep 5, 2019 at 8:38pm
Oops, sorry OP, it wasn't you...
Sep 6, 2019 at 9:39am
Thanks for the various answers. Of course I didn't give all the necessary information. Here's a cut down version of the program with the parts that I think are needed:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>
#define NIL 0
FILE* ifile;
char *in_filename ;

int main(int argc, char *argv[])
{
        char c;
    
        if (argc < 3)
        {
            fprintf(stderr, "Usage:\n\t%s <in-file> <out-file> ", argv[0]) ;
            return 1 ;
        }
        in_filename = *++argv ;
        if((ifile = fopen(in_filename,"r")) == NIL)
            abort_run("Fatal: Unable to open input_file\n") ;
        if((fscanf(ifile, "%c", &c)) == NIL)
           abort_run("Fatal: Unable to read from ifile.\n") ;           
        return 0;
}


“ifile” is a simple text file but the variable “c” in “if((fscanf(ifile, "%c", &c)) == NIL)” is not being being set to the correct value. Everything up to that statement works correctly.
Last edited on Sep 6, 2019 at 9:40am
Sep 6, 2019 at 1:09pm
your code works for me.
I get the first byte from the file.
Sep 6, 2019 at 2:31pm
The first character in "ifile" is 'S' but the program is giving me 'i' as the value of "c".

What change or changes need to be made to get the right value?

Here is my version of the program which builds without problems:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#pragma warning(disable:4430)
#pragma warning(disable:4552)
#pragma warning(disable:4996)

#include <stdio.h>
#include <stdlib.h>
#define NIL 0
FILE* ifile;
char* in_filename ;

int main(int argc,char* argv[])
{
	char c = 'A';

	if(argc < 2)
	{
		fprintf(stderr,"Usage:\n\t%s <in-file> <out-file> ",argv[0]) ;
		return 1 ;
	}
	in_filename = *++argv ;
	if((ifile = fopen(in_filename,"r")) == NIL)
		return(1) ;
	if((fscanf(ifile,"%c",&c)) == NIL)
		return(1) ;
	return 0;
}


Last edited on Sep 6, 2019 at 2:42pm
Sep 6, 2019 at 5:53pm
adding a print to see what the value of c is, I still get the first character in my file.
its working.
add a printf to see what c is .. (how are YOU looking at it?)

good fun:
add the print in the second if statement too. What do these changes do for you..?

1
2
3
4
5
6
7
8
9
return(1) ;
	if((fscanf(ifile,"%c",&c)) == NIL)
{
        printf("oh no! : %c", c); //c will be random junk.  
		return(1) ;
}
       printf("%c", c); //c will be the correct first letter in your text file. 
	return 0;


Last edited on Sep 6, 2019 at 5:58pm
Topic archived. No new replies allowed.