Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

sscanf

tokoGtokoG Posts: 209Member
Hi

I have a question regarding [b]sscanf[/b] function and its use.
I found the explanation of this function and the example of it.

[code]
/* sscanf example */
#include

int main ()
{
char sentence []="Benny is 29 years old";
char str [20];
int i;

sscanf (sentence,"%s %*s %d",str,&i);
printf ("%s -> %d
",str,i);

return 0;
}

Output:
Benny -> 29
[/code]

But, I don't understand why... this part,

[b]
sscanf (sentence,"%s %*s %d",str,&i);
printf ("%s -> %d
",str,i);
[/b]

produces the output of this.

[b]
Benny -> 29
[/b]


Why did only [b]Benny[/b] and [b]29[/b] were pick up??


Thank you!

Comments

  • LundinLundin Posts: 3,711Member
    : Hi
    :
    : I have a question regarding [b]sscanf[/b] function and its use.
    : I found the explanation of this function and the example of it.
    :
    : [code]
    : /* sscanf example */
    : #include
    :
    : int main ()
    : {
    : char sentence []="Benny is 29 years old";
    : char str [20];
    : int i;
    :
    : sscanf (sentence,"%s %*s %d",str,&i);
    : printf ("%s -> %d
    ",str,i);
    :
    : return 0;
    : }
    :
    : Output:
    : Benny -> 29
    : [/code]
    :
    : But, I don't understand why... this part,
    :
    : [b]
    : sscanf (sentence,"%s %*s %d",str,&i);
    : printf ("%s -> %d
    ",str,i);
    : [/b]
    :
    : produces the output of this.
    :
    : [b]
    : Benny -> 29
    : [/b]
    :
    :
    : Why did only [b]Benny[/b] and [b]29[/b] were pick up??
    :
    :
    : Thank you!
    :


    Because only two variables were used.

    "%s goes to str
    %*s doesn't mean a thing and there was no variable to receive it either
    %d goes to i
  • homerocdahomerocda Posts: 87Member
    : (...)
    : %*s doesn't mean a thing and there was no variable to receive it either
    : (...)

    I guess TokoG took the example from this page: http://www.cplusplus.com/ref/cstdio/sscanf.html

    Here the %*s really does mean a thing: read a string, but ignore it.
    It makes sense, since if you hadn't put this the sscanf function would've tried to parse the substring "is" as an integer, what would be an error.

    Homero C. de Almeida

    [italic]There's no dishonour in failure. For we aren't allowed to know wheter we'll achieve success or not. There is only one final shame, the cowardice of not trying.[/italic]

  • tokoGtokoG Posts: 209Member
    Hi Lundin & homerocda

    So.. summing up your advices, [b]sscanf[/b] plays a bit of role like [b]strtok[/b] which to find delimination?

    [b]sscanf[/b] only picked up the [b]first[/b] delimination which is Benny. But it doesn't pick up the WHOLE [b]setence[/b] right?

    And for the result above, %*s is playing a role.... correct?

    But, WITHOUT %*s, [b]Benny[/b] part was still printed out but [b]29[/b] became [b]0[/b]. I thought the result would be [b]Benny is 29 years old -> 29[/b], but it wasn't.

    OR, [b]%*s[/b] part only affects [b]%i (the latter formatted input[/b] but [b]%s[/b] in [b]sscanf[/b] still only prints out the [b]first deliminator[/b]?
  • LundinLundin Posts: 3,711Member
    : : (...)
    : : %*s doesn't mean a thing and there was no variable to receive it either
    : : (...)
    :
    : I guess TokoG took the example from this page: http://www.cplusplus.com/ref/cstdio/sscanf.html
    :
    : Here the %*s really does mean a thing: read a string, but ignore it.
    : It makes sense, since if you hadn't put this the sscanf function would've tried to parse the substring "is" as an integer, what would be an error.
    :
    : Homero C. de Almeida
    :
    : [italic]There's no dishonour in failure. For we aren't allowed to know wheter we'll achieve success or not. There is only one final shame, the cowardice of not trying.[/italic]
    :
    :


    Seems I have forgotten about %* :-)

    But... when parsing a string there are two cases: either you know the format of the string, or you don't. If you know the format of the string, you should write somthing like

    sscanf (sentence,"%s is %d",str,&i);

    If you don't know the format of the string, you will have to iterate it until you find a digit. There is no need for %* in any of these cases.
    It seems like a handy functionality to have, but I wonder if there ever is any use for it...?
  • homerocdahomerocda Posts: 87Member
    : Hi Lundin & homerocda
    :
    : So.. summing up your advices, [b]sscanf[/b] plays a bit of role like [b]strtok[/b] which to find delimination?
    :
    : [b]sscanf[/b] only picked up the [b]first[/b] delimination which is Benny. But it doesn't pick up the WHOLE [b]setence[/b] right?
    :
    : And for the result above, %*s is playing a role.... correct?
    :
    : But, WITHOUT %*s, [b]Benny[/b] part was still printed out but [b]29[/b] became [b]0[/b]. I thought the result would be [b]Benny is 29 years old -> 29[/b], but it wasn't.
    :
    : OR, [b]%*s[/b] part only affects [b]%i (the latter formatted input[/b] but [b]%s[/b] in [b]sscanf[/b] still only prints out the [b]first deliminator[/b]?
    :

    tokoG, have you read the explanation for sscanf on that page?
    sscanf works just like scanf, but reads from a string not standard input.

    %s means "read the next characters until a blank character is found". It would never read the whole sentence unless if it were just a word.

    When it founds a match on the string it starts searching for the match for the next pattern "until it finds a blank character", but starting from where the first match stopped.

    Without the %*s (which means "ignore the next string") it will try to set the next word to an int. But the next word found is not an integer is "is", which can't be translated to a numerical value, so it just sets the variable to 0.

    [code]
    source string = "Benny is 29 years old"
    format string = "%s %*s %i"

    1. Trying to match the first pattern as a string in the source string:

    source string = "Benny is 29 years old"
    +---+

    Benny: string found
    Expecting: %s -> string
    Match! Store it on the first variable passed.

    2. Trying to match the second pattern as a string in the source string:

    source string = "Benny is 29 years old"
    ++

    is: string found
    Expecting: %*s -> string
    Match! Uh-oh, there is the * modifier here, don't store the string found.

    3. Trying to match the third pattern as an integer in the source string:

    source string = "Benny is 29 years old"
    ++

    29: string found
    Expecting: %i -> integer
    Match! 29 can be converted to an integer, so it matches and stores it on the second variable passed.

    There are no more patterns on the format string, stop searching.
    [/code]

    It is surprisingly that you have already used strtok but never used scanf.
    Homero C. de Almeida

    [italic]There's no dishonour in failure. For we aren't allowed to know wheter we'll achieve success or not. There is only one final shame, the cowardice of not trying.[/italic]

  • homerocdahomerocda Posts: 87Member
    :
    : Seems I have forgotten about %* :-)
    :
    : But... when parsing a string there are two cases: either you know the format of the string, or you don't. If you know the format of the string, you should write somthing like
    :
    : sscanf (sentence,"%s is %d",str,&i);
    :
    : If you don't know the format of the string, you will have to iterate it until you find a digit. There is no need for %* in any of these cases.
    : It seems like a handy functionality to have, but I wonder if there ever is any use for it...?
    :

    Yes it can be useful. Suppose that you have a file to read like this:

    [code]
    25 Jhonny Bananas
    57 Mary Apples
    32 Jeff Pineaples
    100 Todd Apples
    22 Jimmy Bananas
    [/code]

    You don't know what the second pattern might be, but you know the lines have a pattern. You just want to know how many of each fruit where sold, it doesn't mather whom you sold it. Would't %*s be useful? ;-)

    Homero C. de Almeida

    [italic]There's no dishonour in failure. For we aren't allowed to know wheter we'll achieve success or not. There is only one final shame, the cowardice of not trying.[/italic]

  • LundinLundin Posts: 3,711Member
    : :
    : : Seems I have forgotten about %* :-)
    : :
    : : But... when parsing a string there are two cases: either you know the format of the string, or you don't. If you know the format of the string, you should write somthing like
    : :
    : : sscanf (sentence,"%s is %d",str,&i);
    : :
    : : If you don't know the format of the string, you will have to iterate it until you find a digit. There is no need for %* in any of these cases.
    : : It seems like a handy functionality to have, but I wonder if there ever is any use for it...?
    : :
    :
    : Yes it can be useful. Suppose that you have a file to read like this:
    :
    : [code]
    : 25 Jhonny Bananas
    : 57 Mary Apples
    : 32 Jeff Pineaples
    : 100 Todd Apples
    : 22 Jimmy Bananas
    : [/code]
    :
    : You don't know what the second pattern might be, but you know the lines have a pattern. You just want to know how many of each fruit where sold, it doesn't mather whom you sold it. Would't %*s be useful? ;-)
    :
    : Homero C. de Almeida
    :
    : [italic]There's no dishonour in failure. For we aren't allowed to know wheter we'll achieve success or not. There is only one final shame, the cowardice of not trying.[/italic]
    :
    :



    Alright, I yield :-)

    Though I would probably not use the scanf functions to read strings, since reading everything charater by character with fgets() is much safer and will detect corrupted data easier.
  • tokoGtokoG Posts: 209Member

    : tokoG, have you read the explanation for sscanf on that page?
    : sscanf works just like scanf, but reads from a string not standard input.
    :
    : %s means "read the next characters until a blank character is found". It would never read the whole sentence unless if it were just a word.
    :
    : When it founds a match on the string it starts searching for the match for the next pattern "until it finds a blank character", but starting from where the first match stopped.
    :
    : Without the %*s (which means "ignore the next string") it will try to set the next word to an int. But the next word found is not an integer is "is", which can't be translated to a numerical value, so it just sets the variable to 0.
    :
    : [code]
    : source string = "Benny is 29 years old"
    : format string = "%s %*s %i"
    :
    : 1. Trying to match the first pattern as a string in the source string:
    :
    : source string = "Benny is 29 years old"
    : +---+
    :
    : Benny: string found
    : Expecting: %s -> string
    : Match! Store it on the first variable passed.
    :
    : 2. Trying to match the second pattern as a string in the source string:
    :
    : source string = "Benny is 29 years old"
    : ++
    :
    : is: string found
    : Expecting: %*s -> string
    : Match! Uh-oh, there is the * modifier here, don't store the string found.
    :
    : 3. Trying to match the third pattern as an integer in the source string:
    :
    : source string = "Benny is 29 years old"
    : ++
    :
    : 29: string found
    : Expecting: %i -> integer
    : Match! 29 can be converted to an integer, so it matches and stores it on the second variable passed.
    :
    : There are no more patterns on the format string, stop searching.
    : [/code]
    :
    : It is surprisingly that you have already used strtok but never used scanf.
    : Homero C. de Almeida
    :
    : [italic]There's no dishonour in failure. For we aren't allowed to know wheter we'll achieve success or not. There is only one final shame, the cowardice of not trying.[/italic]
    :
    :


    Thank you so much for the whole explanation of the sscanf use.
    Including reminding me of hat scanf with string was... I didnt have enough practices to remember the function! But no I made weote some code to text scanf again.

    Your above explanation is very good. Thank you again!
Sign In or Register to comment.