简体   繁体   中英

using scanf to read a string and an int separated by /

The input consists a string and an integer, which are separated by a '/' , like this:

hello/17

And I want to read the input into a string and an int , like this:

char str[20];
int num;
scanf("%s/%d", str, &num);  // this how I tried to do it.

I can't seem to make it, any advice?

scanf awaits a whitespace terminated string when it tries to read %s .

Try to specify the forbidden character set directly:

  scanf("%19[^/]/%d", str, &num);

You can read more about the formating codes here

You only need to run the following program:

#include <stdio.h>

int main (void) {
    char str[20] = {'\0'};
    int count, num = 42;

    count = sscanf ("hello/17", "%s/%d", str, &num);

    printf ("String was '%s'\n", str);
    printf ("Number was %d\n", num);
    printf ("Count  was %d\n", count);

    return 0;
}

to see why this is happening. The output is:

String was 'hello/17'
Number was 42
Count  was 1

The reason has to do with the %s format specifier. From C99 7.19.6.2 The fscanf function (largely unchanged in C11, and the italics are mine):

s : matches a sequence of non-white-space characters.

Since / is not white space, it gets included in the string bit, as does the 17 for the same reason. That's also indicated by the fact that sscanf returns 1 , meaning that only one item was scanned.

What you'll then be looking for is something that scans any characters other than / into the string (including white space). The same section of the standard helps out there as well:

[ : matches a nonempty sequence of characters from a set of expected characters (the scanset). The conversion specifier includes all subsequent characters in the format string, up to and including the matching right bracket (]). The characters between the brackets (the scanlist) compose the scanset, unless the character after the left bracket is a circumflex (^), in which case the scanset contains all characters that do not appear in the scanlist between the circumflex and the right bracket.

In other words, something like:

#include <stdio.h>
int main (void) {
    char str[20] = {'\0'};
    int count, num = 42;

    count = sscanf ("hello/17", "%[^/]/%d", str, &num);

    printf ("String was '%s'\n", str);
    printf ("Number was %d\n", num);
    printf ("Count  was %d\n", count);

    return 0;
}

which gives you:

String was 'hello'
Number was 17
Count  was 2

One other piece of advice: never ever use scanf with an unbounded %s or %[ ; you're asking for a buffer overflow attack. If you want a robust user input function, see this answer .

Once you have it in as a string, you can sscanf it to your heart's content without worrying about buffer overflow (since you've limited the size on input).

Could be like that:

char str[20];
int num;

scanf("%19[^/]%*c%d", str, &num);

%*c reads one character and discards it

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM