我希望我的用户将 3 个不同的年龄放入括号中并用逗号分隔。所以它看起来像这样 {int,int,int}。
我尝试过:
int a,b,c;
if(scanf("{ %d , %d , %d }", &a,&b,&c)!=3){
printf("Bad format");
}
但它没有正确拒绝像 { 1, 2, 3,
我想允许:
{1,2,3}
{ 1 , 2 ,3 }
{ 1 , 2 , 3}
并拒绝:
{1,2,3,4}
{1 2 3 4}
1234
1 2 3 4
等等
谢谢。
最佳答案
(这个答案有些是固执己见的。抱歉。我有意见。)
scanf
确实不是精确验证输入的理想工具。特别是,它通常不区分换行符和其他空格,这一事实使得验证严格面向行的输入确实非常困难。
另一方面,如果您已经拥有所有标点符号,也许您应该准备好接受更多自由格式的输入。为什么用户不应该在两行甚至五行上输入数据:
{
1,
2,
3
}
(或者Pythonesquely:
{ 1
, 2
, 3
}
:-) )
除非您竭尽全力禁止它们,或者使用此处通常建议的 fgets/sscanf
解决方法,否则以上所有内容都将被接受。这可能会让某些用户高兴,你永远不知道。
但是,还有另一个问题可能值得尝试解决。在这里,您希望确保三元组以右大括号 }
正确终止,而仅将 }
放入模式中是无法做到这一点的。如果您需要验证最后一次转换之后出现的字符,则需要将该字符设置为转换(以便它成为最后一次转换)。否则,scanf
将简单地将不匹配的输入字符保留在输入流中,并报告所有数据转换均成功。
所以你可以使用这样的东西:
int a,b,c;
char brace;
if (scanf("{ %d , %d , %d %c", &a, &b, &c, &brace) != 4
|| brace != '}') {
printf("Bad format");
}
这保证有一个}
,前面可能有空格。然而,它
不保证 }
是该行的最后一个内容。由于它小心翼翼地不会跳过模式后的空格,因此您可以通过使用 fgets 读取该行(它将读取并包括尾随换行符)来检查该行的其余部分是否为空,然后检查读取的字符以确保它们都满足 isspace()
。
或者您可以让用户将换行符放在他们想要的任何位置。
关于c - 如何使用 SCANF 只允许特定格式的输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53053414/