在scanf中使用的目的是什么?

我遇到了一些代码,并想知道最初的开发人员是做什么的。 以下是使用此模式的简化程序:

#include  int main() { char title[80] = "mytitle"; char title2[80] = "mayataiatale"; char mystring[80]; /* hugh ? */ sscanf(title,"%[^a]",mystring); printf("%s\n",mystring); /* Output is "mytitle" */ /* hugh ? */ sscanf(title2,"%[^a]",mystring); /* Output is "m" */ printf("%s\n",mystring); return 0; } 

scanf的手册页有相关信息,但我无法阅读它。 使用这种表示法的目的是什么? 它想要完成什么?

字符类的主要原因是%s符号在第一个空格字符处停止,即使您指定了字段长度,并且您经常不希望它。 在这种情况下,字符类表示法可能非常有用。

考虑这段代码读取最多10个字符的行,丢弃任何多余的字符,但保留空格:

 #include  #include  int main(void) { char buffer[10+1] = ""; int rc; while ((rc = scanf("%10[^\n]%*[^\n]", buffer)) >= 0) { int c = getchar(); printf("rc = %d\n", rc); if (rc >= 0) printf("buffer = <<%s>>\n", buffer); buffer[0] = '\0'; } printf("rc = %d\n", rc); return(0); } 

这实际上是关于与getline()变体相关的comp.lang.c.moderated(大约2004年6月)讨论的示例代码。


至少有一些混乱占主导地位。 第一个格式说明符%10[^\n] ,最多可读取10个非换行符,并将它们分配给缓冲区以及尾随空值。 第二个格式说明符%*[^\n]包含赋值抑制字符( * ),并从输入中读取零个或多个剩余的非换行符。 当scanf()函数完成时,输入指向下一个换行符。 循环体读取并打印该字符,这样当循环重新开始时,输入正在查看下一行的开头。 然后重复该过程。 如果该行短于10个字符,则将这些字符复制到缓冲区,并且“零或多个非换行”格式处理零非换行。

%[a]%[^a]这样的结构存在,因此scanf()可以用作一种词法分析器。 它们有点像%s ,但它们不是收集尽可能多的“字符串”字符的范围,而是收集字符类所描述的字符范围。 可能有些情况下写%[a-zA-Z0-9]可能有意义,但我不确定我看到一个引人注目的用例与scanf()补充类。

恕我直言, scanf()根本不适合这项工作。 每次我打算使用其中一个更强大的function时,我最终都会将其剥离并以不同的方式实现该function。 在某些情况下,这意味着使用lex来编写一个真正的词法分析器,但通常在I / O时行,并在进行值转换之前用strtok()将其粗略地分解为令牌就足够了。

编辑:我结束了翻录scanf()通常是因为当面对坚持提供错误输入的用户时,它只是不善于帮助程序提供有关问题的良好反馈,并且有一个汇编程序打印“错误,终止”。 因为它唯一有用的错误信息与我的用户不太一致。 (在这种情况下,我。)

这就像正则表达式中的字符集; [0-9]匹配一串数字, [^aeiou]匹配任何非小写元音等。

有各种各样的用途,例如拉出数字,标识符,空格块等。

您可以在线获得ISO / IEC9899标准的相关内容 。

以下是我从文件中引用的一段[ (第286页):

匹配一组预期字符的非空字符序列。

转换说明符包括格式字符串中的所有后续字符,包括匹配的右括号(])。 括号(扫描列表)之间的字符组成扫描集,除非左括号后面的字符是抑扬符(^),在这种情况下,扫描集包含旋转和右括号之间的扫描列表中未出现的所有字符。 如果转换说明符以[]或[^]开头,则右括号字符位于扫描列表中,下一个右括号字符是结束规范的匹配右括号; 否则第一个右括号字符是结束规范的字符。 如果 – 字符在扫描列表中并且不是第一个字符,也不是第一个字符是^的第二个字符,也不是最后一个字符,则行为是实现定义的。