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