【问题标题】:What does '|' mean in scanf format string'|' 是什么意思scanf 格式字符串的意思
【发布时间】:2018-08-28 19:23:41
【问题描述】:
char szA[256]={0}; 
scanf("%[^a]%s",&szA);   //failed when trailing string 
scanf("%[^a]|%s",&szA);   //worked whatever the input 

'|' 是什么意思表示格式字符串。我找不到官方规范。有没有人可以给我一些线索?

当我输入带有多个“|”的内容时,后一个仍然有效(只是意味着程序没有崩溃)。它不需要在格式字符串之后给出两个缓冲区。前一个在输入字符串可以分成多个字符串时崩溃。因此,它们之间还有其他区别。它是什么 ?

所以,我不明白为什么当缓冲区数小于指令数而前一个失败时,后一个工作。或者有人可以给我一个输入字符串以使后者崩溃。

【问题讨论】:

  • “作品”对于scanf 来说是一个非常不精确的词。如果格式包含与输入不匹配的文字字符,则 scanf 将停止扫描。由于它总是返回成功转换的次数,因此您甚至无法判断它是否提前停止,除非在文字字符之后有转换。在这种情况下,您可能会看到 scanf 返回 1,这就是为什么它在尝试将字符串存储到不存在的参数时不会崩溃的原因。如果这对您“有效”,那么我想您很幸运。
  • 是的。感谢您的建议。 “作品”在这里仅表示未损坏。我会注意字的精确度。 :)

标签: c++ c scanf placeholder


【解决方案1】:

'|' 是什么意思表示格式字符串。我找不到官方规范。有没有人可以给我一些线索?

这意味着代码需要输入流中的文字|

话虽如此,格式说明符不起作用。

%[^a] 部分将捕获所有不是a 的字符。这意味着它甚至会从输入流中捕获|。当流中遇到字符 a 时,它将停止捕获。当然,这与格式字符串中的文字 | 不匹配。因此,之后的任何内容都不会被处理。

如果我将输入 def|akdk 提供给以下程序

#include <stdio.h>

int main()
{
   char szA[256] = {0}; 
   char temp[100] = {0};
   int n = scanf("%[^a]|%s", szA, temp);
   printf("%d\n%s\n%s\n", n, szA, temp);
}

我得到以下输出

1
def|

这很有意义。顺便说一句,输出中的最后一行是空行。我不确定如何在答案中表明这一点。

当我将scanf 行更改为

   int n = scanf("%[^a]a%s", szA, temp);

我得到以下输出

2
def|
kdk

这很有意义。

【讨论】:

  • 当我输入带有多个“|”的内容时,后一个仍然有效。它不需要在格式字符串之后给出两个缓冲区。前一个在输入字符串可以分成多个字符串时崩溃。因此,它们之间还有其他区别。这是什么?
  • @W.Perrin,请查看更新后的答案。希望现在有意义。
【解决方案2】:

它不是格式说明符之一,因此它是一个 literal | 字符,这意味着它必须存在于输入流中。 官方规范是在 ISO 标准中找到的标题为 The fscanf function 的部分(例如,C11 7.21.6.2),相关部分声明:

格式由零个或多个指令组成:一个或多个空白字符、普通多字节字符(既不是 % 也不是空白字符)或转换规范。

一个普通的多字节字符指令通过读取流的下一个字符来执行。如果这些字符中的任何一个与构成指令的字符不同,则该指令将失败,并且不同的字符和后续字符仍然未读。


您可以在以下完整程序中看到效果,当您查找文字 _ 时无法扫描 "four|1",但在查找 | 时工作正常。

#include <stdio.h>

int main(void) {
    char cjunk[100];
    int ijunk;
    char inStr[] = "four|1";
    if (sscanf(inStr, "%4s_%d", cjunk, &ijunk) != 2)
        printf ("Could not scan\n");
    if (sscanf(inStr, "%4s|%d", cjunk, &ijunk) == 2)
        printf ("Scanned okay\n");
    return 0;
}

【讨论】:

    【解决方案3】:

    所以,经过一番交谈,在我的理解中,后者要求剩余的流以“|”开头在处理 '|%s' 指令时。而前一个指令排除了“a”并留下剩余的流以“a”开头。所以尾随指令总是不匹配任何东西,也不需要将任何东西放入缓冲区。因此,即使没有给出缓冲区,它也永远不会崩溃。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-04-08
      • 2015-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-28
      • 1970-01-01
      相关资源
      最近更新 更多