14

输入由一个字符串和一个整数组成,它们由 a 分隔'/',如下所示:

hello/17

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

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

好像做不出来,有什么建议吗?

4

3 回答 3

17

scanf尝试读取时等待以空格结尾的字符串%s

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

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

您可以在此处阅读有关格式化代码的更多信息

于 2012-10-16T07:52:44.307 回答
9

您只需要运行以下程序:

#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%sor %[; 您要求进行缓冲区溢出攻击。如果您想要一个强大的用户输入功能,请参阅此答案

一旦你把它作为一个字符串输入,你就可以随心所欲地使用sscanf它,而不必担心缓冲区溢出(因为你已经限制了输入的大小)。

于 2012-10-16T07:58:50.290 回答
0

可能是这样的:

char str[20];
int num;

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

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

于 2019-11-04T08:22:26.550 回答