热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

Theinputconsistsastringandaninteger,whichareseparatedbya,likethis:输入包含一个字符串和一个整数,

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:

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

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?

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

2 个解决方案

#1


13  

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

scanf在尝试读取%s时等待以空格终止的字符串。

Try to specify the forbidden character set directly:

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

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

You can read more about the formating codes here

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

#2


8  

You only need to run the following program:

您只需要运行以下程序:

#include 

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格式说明符有关。来自C99 7.19.6.2 fscanf函数(在C11中基本不变,斜体是我的):

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

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

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.

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

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 
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, you're asking for a buffer overflow attack. If you want a robust user input function, see this answer.

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

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).

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


推荐阅读
author-avatar
huo斌_340
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有