Valhalla Legends Forums Archive | C/C++ Programming | sscanf function

AuthorMessageTime
touchstone
[code]

include<stdio.h>
#include<stdlib.h>


int main()


{

FILE *infile = fopen("d:\\sample.txt","r");

if(infile ==NULL) printf("can not open ");


char buff[90];

int n ;

while(!feof(infile))

{

fgets(buff,70,infile);

sscanf(buff,"%d",&n);

printf("%d\n",n);

}

}

[/code]

sample.txt
--------------
16 18 20 25 18 23 22 55

11 22 23 25 28 29 27 31

4 2 78 67 90 23 25 56

12 0 16 17 87 79 0 89


ouput of the program
-----------------------------
16
16
11
11
4
4
12
12
12


why the data has been repeated two times ?

why not the output like below?

16
11
4
12

any explanation?

February 4, 2004, 6:40 PM
Yoni
Haven't read entire source code, but I spotted the most likely source of the problem.

[quote author=touchstone link=board=30;threadid=5082;start=0#msg42559 date=1075920046]
[code]
sscanf(buff,"%d",&n);
[/code]
[/quote]
When you use "%d" as a format string for *scanf, it reads an integer and that's it. The next time you try to read, it'll encounter the whitespace and fail.
You can instruct *scanf to skip whitespaces by adding a space in the format string, as such:

[code]
sscanf(buff, "%d ", &n);
[/code]

(I changed the string from "%d" to "%d ", by adding a space after the d.)
February 4, 2004, 6:59 PM
MoNksBaNe_Agahnim
[code]
while(!feof(infile))
[/code]

maybe make it f.eof() ... not sure but that is what you have to do with fstream
February 4, 2004, 8:56 PM
Kp
[quote author=MoNksBaNe_Agahnim link=board=30;threadid=5082;start=0#msg42582 date=1075928187][code]while(!feof(infile))[/code]maybe make it f.eof() ... not sure but that is what you have to do with fstream[/quote]

No. If you look at his code, nowhere does there exist a variable f which could even have an eof method.

If you're only scanning one number, I'd suggest using strtol instead. Just a matter of preference.
February 4, 2004, 10:30 PM
touchstone
hi i did this (added space after %d)
as per your suggestion....
[code]

sscanf(buff, "%d ", &n);

[/code]

still... it it did not give me result.

why it is not giving. i am learning to use fgets() and sscanf()

do you think i have done any mistake in the code?

...but according to logic it should print the number only once. is not it?i think my logic is correct.

datas are poured into buff and then sscanf is extracting out the integer from the buff string.

i am trying a lot to find out the cause....but could not....whats wrong?
February 5, 2004, 3:24 AM
iago
Your code looks fine, except:
Max Length should be a constant (your buffer length and the amount you get can be the same)
If the file can't be opened, it will still try reading it
Besides those, it looks great.. I don't have a C compiler here, but I will try it in Linux

<edit>
include <stdio.h> should be #include <stdio.h> (I assume that's a copy mistake)
<edit2>
hah, I found the problem just before I ran it. The problem is that the file has blank lines, which are read in and they aren't parsed correctly.
</edit2>
</edit>
February 5, 2004, 12:42 PM
touchstone
>Max Length should be a constant

what do you mean? i have alloted maximum 90 character in the buff[]....its enough.

>If the file can't be opened

well, file is opening... i did not do NULL checking.
...but no doubt its opening

>include <stdio.h> should be #include <stdio.h>
yes....its a copy mistake.

> found the problem just before I ran it. The problem is that the file has blank lines, which are read in and they aren't parsed correctly.

....i am not agree with you.

let me explain why....

fget() will read 70 elements ...... as soon as it gets a newline it will stop and it will insert newline into buff and also a '\0' character will be automatically added into buff.

file pointer is now in the next row(because of newline)


now sscanf() will extract the first integer stored in the buff.


this should be the case for one go of the while loop.

same thing will be repeating until fget() returns end of file.

i am just experimenting with this code to understand the behaviour of fgets() and sscanf()

but i did not find any answer why i am getting wrong output.

thanks








February 5, 2004, 2:01 PM
iago
[quote author=touchstone link=board=30;threadid=5082;start=0#msg42647 date=1075989684]
>Max Length should be a constant

what do you mean? i have alloted maximum 90 character in the buff[]....its enough.
[/quote]
I mean, it is better coding practice to do this:
#define MAXLENGTH 90
...
char line[MAXLENGTH];
...
fgets(line, MAXLENGTH, file);
...

[quote]
>If the file can't be opened

well, file is opening... i did not do NULL checking.
...but no doubt its opening
[/quote]
But if the file doesn't open for some reason, it will still attempt to process and die.

[quote]> found the problem just before I ran it. The problem is that the file has blank lines, which are read in and they aren't parsed correctly.

....i am not agree with you.

let me explain why....

fget() will read 70 elements ...... as soon as it gets a newline it will stop and it will insert newline into buff and also a '\0' character will be automatically added into buff.

file pointer is now in the next row(because of newline)
[/quote]

You're exactly right. But your file looks like this:
[code]16 18 20 25 18 23 22 55\n
\n
11 22 23 25 28 29 27 31\n
\n
4 2 78 67 90 23 25 56\n
\n
12 0 16 17 87 79 0 89EOF[/code]

After it reads the first line, it reads the second, which is simply "\n". The sscanf() runs and does nothing, because there is nothing there to parse. Then the string is displayed, but because sscanf() did nothing, the string hasn't changed.

Try checking the return value of sscanf() (I forget what it should be, but you can look it up) to see if anything happened before displaying.

February 5, 2004, 5:44 PM
Skywing
sscanf returns the number of arguments scanned in, so you should compare it to 1 in this situation.
February 5, 2004, 7:42 PM
iago
[quote author=Skywing link=board=30;threadid=5082;start=0#msg42669 date=1076010178]
sscanf returns the number of arguments scanned in, so you should compare it to 1 in this situation.
[/quote]

Ah, that's what I thought, but I wasn't 100% sure so I didn't want to say. Thanks!
February 5, 2004, 8:08 PM
touchstone
hi, i was away for some days....

however, i am convinced by your explanation....i hava understood the cause of mine previous output.

and i should go for checking of sscanf() conversion before printing.

i wrote
[code]

.........
..........
int p = sscanf(buff,"%d",&n);
if(p==1)
{

printf("%d\n",n);
............

[/code]

....and this checking is giving
16
11
4
12

its ok now. ....thanks
February 8, 2004, 7:11 PM
iago
Another way to do it would be this:
[code]if(sscanf(buff,"%d",&n) == 1)
{
....
}[/code]
February 8, 2004, 7:13 PM

Search