c - 为什么这个 scanf() 转换实际上有效?

标签 c scanf

啊,这是一个古老的故事,程序员逐渐编写一些代码,他们不希望做任何超出预期的事情,但代码出乎意料地做了所有事情,而且也正确。

我正在解决一些 C 编程练习问题,其中一个是将 stdin 重定向到其中包含一些代码行的文本文件,然后使用 scanf() 和 printf() 将其打印到控制台。我在打印换行符时也遇到了麻烦(因为 scanf 通常会吃掉空格字符),并且当我决定重新开始并最终输入以下内容时,我输入了一堆涉及多个条件和标志的困惑代码:

(其中 c 是一个足够大的字符缓冲区,可以容纳整个文本文件的内容)

scanf("%[a-zA-Z -[\n]]", c);
printf("%s", c);

瞧,这一切都很完美。我试图通过创建字符类的变体(在外面的括号之间)来找出原因,例如:

[\w\W -[\n]]
[\w\d -[\n]]
[. -[\n]]
[.* -[\n]]
[^\n]

但这些都不起作用。他们最终要么只读到一个字符,要么产生一堆杂乱的随机字符。 '[^\n]' 不起作用,因为文本文件包含换行符,因此它只打印出一行。

由于我还没有弄清楚,我希望有人能知道这两个问题的答案:

  • 为什么“[a-zA-Z -[\nn]]”能按预期工作?
  • 文本文件包含字母、数字和符号(“:”、“-”、“>”,也许还有其他一些);如果“a-z”的意思是“从unicode“a”到unicode“z”的所有字符”,那么“a-zA-Z”如何也包含数字?
  • 看起来你可以在括号内输入的内容的语法很像正则表达式(我在Python中熟悉它),但不完全一样。我已经阅读了尝试解决这个问题时可以使用的内容,但我无法找到任何将此语法与正则表达式进行比较的信息。那么:它们有何相似之处和不同之处?

我知道这对于 scanf 来说可能不是一个好的用法,但由于它来自实践问题,因此对于这种用法必须暂时忽略现实世界的约定。

谢谢!

最佳答案

您正在选取数字,因为您的字符集中有“-[”。这意味着从空格 (32) 到开括号 (91) 的所有字符,其中包括 ASCII 中的数字 (48-57)。

您的其他示例也包含此内容,但它们缺少“a-zA-Z”,它可以让您选择小写字母 (97-122)。像 '\w' 这样的序列在字符串本身中被视为未知的转义序列,因此 \w 只是变成单个 w.* 按字面意思理解。它们没有像正则表达式那样的特殊含义。

关于c - 为什么这个 scanf() 转换实际上有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36490898/

相关文章:

c - 将 CSV 文件中的值读入变量

c - 使用 C 中的 if 语句请求输入两次

C 线程在访问非共享资源时给出垃圾输出

c - Structure程序编译没有错误,但控制台窗口没有结果?

c - 如何设置 cron 作业以每小时运行一次可执行文件?

c - 在 C 中为动态数字输入读取字符串时出现问题

c - 如何在另一个线程完成工作之前挂起一个线程

c - 函数中 fgets 的格式化问题

c - 在此代码中除了使用 gets(c) 和 gets(s) 之外,还有什么替代方案?

c++ - scanf_s 错误 Visual Studio