使用scanf读取字符串和由/分隔的int

时间:2012-10-16 07:46:37

标签: c scanf

输入包含一个字符串和一个整数,由'/'分隔,如下所示:

hello/17

我想将输入读入字符串和int,如下所示:

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

我似乎无法做到,有什么建议吗?

3 个答案:

答案 0 :(得分:13)

scanf在尝试阅读%s时等待以空格分隔的字符串。

尝试直接指定禁用字符集:

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

您可以阅读有关格式代码here

的更多信息

答案 1 :(得分:8)

您只需运行以下程序:

#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;
}

了解为什么会这样。输出是:

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

原因与%s格式说明符有关。从C99 7.19.6.2 The fscanf function(在C11中基本没有变化,斜体是我的):

  

s:匹配一系列非空格字符。

由于/不是空格,因此它会包含在字符串位中,因为17出于同样的原因。这也表明sscanf返回1,这意味着只扫描了一个项目。

您将要查找的内容是将其他中的任何字符扫描到字符串(包括空格)中,而不是/。标准的同一部分也有帮助:

  

[:匹配一组预期字符(扫描集)中的非空字符序列。转换说明符包括格式字符串中的所有后续字符,包括匹配的右括号(])。括号(扫描列表)之间的字符组成扫描集,除非左括号后面的字符是抑扬符(^),在这种情况下,扫描集包含在旋转和右括号之间的扫描列表中不出现的所有字符。

换句话说,比如:

#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;
}

给你:

String was 'hello'
Number was 17
Count  was 2

另一条建议:永远永远使用scanf与无界%s,你要求缓冲区溢出攻击。如果您需要强大的用户输入功能,请参阅this answer

一旦你把它作为一个字符串,你可以sscanf它的内容,而不用担心缓冲区溢出(因为你限制了输入的大小)。

答案 2 :(得分:0)

可能是这样:

char str[20];
int num;

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

%*c读取一个字符并将其丢弃