我已经搜索并读到^修饰符声明忽略你放在scanf
中的[]内的任何内容。例如:
int val;
scanf("%[^abc] %d, &val);
printf("val is %d", val);
现在,如果我输入abc42,我认为abc将被忽略,42将被存储到val中。但是,这并没有发生。
我还尝试通过制作scanf
来抑制它:
scanf("%*[^abc] %d, &val);
但这也不起作用。所以我对^实际上做了什么很困惑。
答案 0 :(得分:6)
如果您希望scanf
忽略某些字符,我认为您的意思是希望scanf
读取这些字符,然后忽略它们。为此,您使用%*[]
格式说明符:
scanf("%*[abc] %d", &val);
[abc]
告诉scanf
读取括号之间的任意数量的字符(即a,b或c)。 *
告诉scanf
忽略这些字符,然后%d
将值读入val
。
^
说明符告诉scanf
读取任意数量的字符其他而不是括号之间的字符,这与您想要做的相反,我认为
答案 1 :(得分:5)
您需要仔细阅读scanf(3) 的文档并在编译时启用所有警告(例如gcc -Wall -Wextra -g
如果使用GCC ...);你可能会被这样的汇编警告过。您还应该使用scanf
的结果并在调试器中运行您的程序(gdb
)
scanf("%[^abc] %d", &val);
正在阅读两个项目,第一项是在{a
,b
,c
}之外的一系列字符(第二个是“无处”的整数)
所以你的程序有undefined behavior(UB)因为你用一个小于它应该的参数调用scanf
,并且因为第一个参数应该是一个足够宽的char
缓冲区的位置。 UB可以是bad,所以你需要始终避免它。
您可以尝试:
int val= 0;
char buf[32]; // 30+1 could be enough....
memset (buf, 0, sizeof(buf));
if (scanf("%30[^abc] %d", buf, &val) == 2) {
printf("got string %s and int %d\n", buf, val);
}
else { // handle scanf failure
}
答案 2 :(得分:2)
在编译代码时,它会给出以下警告消息。
test.c:5:2:警告:格式'%[^ abc'需要类型为'char *'的参数,但参数2的类型为' int *'[-Wformat]
test.c:5:2:警告:格式'%d'需要匹配的'int *'参数[-Wformat]
使用它时,必须将字符数组传递给scanf函数。
因此,将scanf行修改为下面,并检查会发生什么。
char buf[100];
int val;
scanf("%[^[abc] %d",buf,&val);
%[^ abc]它读取字符串,如果括号中除^之外的任何字符出现,它将用读取字符填充字符数组的地址。 因此,仅在我们读取字符串输入时才使用它。