^scanf修改器实际上做什么?
我已经搜索并阅读到,^修饰符声明忽略您在^scanf修改器实际上做什么?,c,scanf,C,Scanf,我已经搜索并阅读到,^修饰符声明忽略您在scanf中[]内放置的任何内容。例如: int val; scanf("%[^abc] %d, &val); printf("val is %d", val); 现在,如果我输入abc42,我想abc会被忽略,42会被存储到val中。但是,这不会发生 我还试图通过以下方式抑制scanf: scanf("%*[^abc] %d, &val); 但这也不起作用。因此,我对^的实际用途感到困惑。您需要仔细阅读的文档,并在编译时
scanf
中[]内放置的任何内容。例如:
int val;
scanf("%[^abc] %d, &val);
printf("val is %d", val);
现在,如果我输入abc42,我想abc会被忽略,42会被存储到val中。但是,这不会发生
我还试图通过以下方式抑制scanf
:
scanf("%*[^abc] %d, &val);
但这也不起作用。因此,我对^的实际用途感到困惑。您需要仔细阅读的文档,并在编译时启用所有警告(例如,
gcc-Wall-Wextra-g
如果使用;你可能已经收到过这样的警告。您还应该使用scanf的结果并在调试器中运行程序(gdb
)
正在读取两个项目,第一个是集合{a
,b
,c
}之外的字符串(第二个是“无处”的整数)
因此,您的程序具有(UB),因为您调用scanf
时使用的参数比它应该使用的参数少,并且因为第一个参数应该是足够宽的char
缓冲区的位置。UB可能是真的,所以你需要一直避免它
您可以尝试:
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
}
当你说希望
scanf
忽略某些字符时,我想你的意思是希望scanf
读取这些字符,然后忽略它们。为此,请使用%*[]
格式说明符:
scanf("%*[abc] %d", &val);
[abc]
告诉scanf
读取括号中任意数量的字符(即a、b或c)。*
告诉scanf
忽略这些字符,然后%d
将值读入val
^
说明符告诉scanf
读取括号中字符以外的任意数量的字符,我认为这与您想要执行的操作相反。编译代码时,它会给出以下警告消息
test.c:5:2:警告:格式“[^abc”要求参数类型为“char*”,但参数2的类型为“int*”[-Wformat]test.c:5:2:警告:格式“%d”需要匹配的“int*”参数[-Wformat] 使用此函数时,必须将字符数组传递给scanf函数 因此,将scanf行修改为bellow,并检查发生了什么
char buf[100];
int val;
scanf("%[^[abc] %d",buf,&val);
它读取字符串的%[^abc],如果括号中出现“^is”以外的任何字符,它将用读取字符填充字符数组的地址。
因此,这仅在我们读取字符串输入时使用。您的代码示例的引号不匹配。请准确地发布您正在尝试的代码。次要:不清楚为什么32分之二、30分之二与
char buf[32];…scanf(“%30[^abc]%d”,…
。预期为1。确实想要[
中的2%[^[abc]%d”?你可以在括号前面使用反斜杠,比如scanf(“%[^[abc]”,buf);你的评论示例中没有反斜杠“%[^[abc]”。哦,对不起,我忘了把它放在括号前面。”%[^[abc]”“\[
不是C中定义的转义序列。所以“%[^[abc]”
是个问题。不清楚为什么这个答案建议使用“%[^[abc]
而不是”%[^abc]
。如果删除scanf中的空格,则会失败。这是为什么?
char buf[100];
int val;
scanf("%[^[abc] %d",buf,&val);