【问题标题】:What does scanf("%*[\n] %[^\n]", input_string); do?scanf("%*[\n] %[^\n]", input_string); 是什么意思?做?
【发布时间】:2017-12-29 21:49:21
【问题描述】:

我无法理解其中的区别。我使用%[^\n]s 来获取用户输入的短语。但是当我需要添加两个短语时,这不起作用。但是上面那一个做到了。请帮助我了解其中的区别。

【问题讨论】:

  • 稍微澄清一下您的问题,发送Minimal, Complete, and Verifiable example 并显示您已经进行的编码尝试。您的示例应包括各种示例输入(说明所有方面)和所需的输出。
  • 感谢 Akira 的输入,我从 David 那里得到了正确的信息。我的意思是当我们写类似 printf("%[^\n]s").

标签: c string scanf


【解决方案1】:

%[\n] 指令告诉scanf() 匹配换行符,* 标志表示不应进行分配,因此%*[\n] 跳过任何前导换行符(假设有 em> 至少有一个领先的\n 字符:稍后会详细介绍)。第一个指令后面有一个空格,因此在最后一个 %[^\n] 指令之前会跳过零个或多个空白字符,该指令匹配字符直到遇到换行符。这些存储在input_string[] 中,换行符留在输入流中。使用此格式字符串的后续调用将跳过此剩余的换行符。

但是,这里可能不需要%*[\n] 指令,因为\n 是一个空格字符;使用格式字符串中的前导空格可以完成几乎相同的操作:" %[^\n]"

两者之间的一个区别:"%*[\n] %[^\n]" 期望在输入的开头有一个换行符,没有这个匹配失败并且scanf()返回而不进行任何分配,而@ 987654333@ 不需要前导换行符,甚至前导空白字符(但如果存在则跳过它们)。

如果您改用"%[^\n]",正如问题正文中所建议的那样(注意尾随s 不是scanset 指令的一部分),对scanf() 的第一次调用将匹配字符直到换行遇到。匹配的字符将存储在input_string[] 中,换行符将保留在输入流中。然后,如果使用此格式字符串再次调用scanf(),则在遇到换行符之前不会匹配任何字符,因此如果没有赋值,匹配就会失败。

请注意,在scanf() 格式字符串中使用%s%[] 时,应始终指定最大宽度以避免缓冲区溢出。对于%s%[]scanf() 会自动添加\0 终止符,因此您必须确保为此留出空间。对于大小为 100 的数组,最大宽度应为 99,这样在添加空终止符之前,最多可以匹配并存储 99 个字符。例如:" %99[^\n]"

【讨论】:

    【解决方案2】:

    在 scanf 函数中,'*' 告诉函数忽略输入中的字符。

    %*[\n]
    

    这告诉函数忽略第一个'\n'字符,然后接受任何字符串

    运行代码并首先输入“ENTER”作为输入,然后输入“我感觉很棒!!!” 现在打印缓冲区。你会得到我感觉很好!!!作为输出

    试试这个代码sn-p

    int main()
    {
         char buffer[100];
         printf("Enter a string:"),scanf("%*[\n] %[^\n]', buffer),printf("buffer:%s\n", buffer);
         return 0;
    }
    

    【讨论】:

    • 就像现在一样,这段代码不会编译(逗号分隔的语句?但请检查引号)。为什么用户需要在此处输入输入之前按ENTER?阅读我上面的答案以找出答案......
    【解决方案3】:

    %[^\n]scanf() 的编辑转换代码,可替代gets(str)

    gets(str) 不同,带有 %s 的 scanf() 不能读取多个单词。 使用%[^\n]scanf() 甚至可以读取带有空格的字符串。

    当遇到换行符时,它将终止接收用户的字符串输入。

    【讨论】:

      猜你喜欢
      • 2017-07-27
      • 2015-07-15
      • 2015-09-02
      • 2020-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-26
      • 1970-01-01
      相关资源
      最近更新 更多