[英]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:我想将输入读入一个字符串和一个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?我似乎无法做到,有什么建议吗?
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.原因与%s
格式说明符有关。 From C99 7.19.6.2 The fscanf function
(largely unchanged in C11, and the italics are mine):从 C99 7.19.6.2 The fscanf function
(在 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.由于/
不是空格,它被包含在字符串位中,出于同样的原因, 17
也是如此。 That's also indicated by the fact that sscanf
returns 1
, meaning that only one item was scanned. 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 <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 %[
;另外一个忠告:永远用不完scanf
采用无界%s
或%[
; 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).一旦将它作为字符串输入,您就可以将它sscanf
到您想要的内容,而不必担心缓冲区溢出(因为您限制了输入的大小)。
Could be like that:可能是这样的:
char str[20];
int num;
scanf("%19[^/]%*c%d", str, &num);
%*c
reads one character and discards it %*c
读取一个字符并丢弃它
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.