scanf() 函数中的扫描集有什么区别? [英] what is the difference between scansets in scanf() function?

查看:41
本文介绍了scanf() 函数中的扫描集有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了关于这些的所有问题,但我还没有找到对 %[^\n]s%[^\n] 之间区别的解释scanf() 函数中的代码>.

解决方案

%[^\n] 之后的额外 s 是一个常见的错误.它可能来自扫描集和 %s 转换说明符之间的混淆.

它在 scanf 格式字符串中的效果是匹配输入流中的 s 字节.这样的匹配总是会失败,因为在成功转换 %[^\n] 说明符之后,流要么位于文件末尾,要么挂起的字符是换行符.除非格式字符串中有进一步的转换说明符,否则此失败不会影响 scanf() 的返回值,因此此错误很少成为问题.

还要注意这些警告:

  • %[^\n] 说明符将在空行上失败.
  • 始终为 %[]%s 说明符指定要转换的最大字节数更安全,以避免意外大输入的未定义行为.
  • scanf("%99[^\n]", line) 将使输入流中的换行符处于挂起状态,您必须使用它才能读取具有相同 scanf 格式字符串.

while (fgets(line, sizeof line, stdin)) { ... } 相反,你不能简单地写 while (scanf("%99[^\n]", line) == 1) { ... } 要逐行读取整个文件,必须在循环体中消耗待处理的换行符,循环将在第一个空行处停止.

示例:

字符行[100];if (scanf("%99[^\n]", line) == 1) {/* 处理输入行 */} 别的 {/* 流位于文件末尾或有一个空行 */}

I have read all of the questions about these, but I have not found an explanation for the difference between %[^\n]s and %[^\n] in the scanf() function.

解决方案

The extra s after %[^\n] is a common mistake. It may come from a confusion between scansets and the %s conversion specifier.

Its effect in a scanf format string is a match for an s byte in the input stream. Such a match will always fail because after the successful conversion of the %[^\n] specifier, the stream is either at end of file or the pending character is a newline. Unless there are further conversion specifiers in the format string, this failure will have no effect on the return value of scanf() so this bug is rarely an issue.

Note also these caveats:

  • the %[^\n] specifier will fail on an empty line.
  • it is safer to always specify the maximum number of bytes to convert for the %[] and %s specifiers to avoid undefined behavior on unexpectedly large inputs.
  • scanf("%99[^\n]", line) will leave the newline pending in the input stream, you must consume it before you can read the next line with the same scanf format string.

Contrary to while (fgets(line, sizeof line, stdin)) { ... }, you cannot simply write while (scanf("%99[^\n]", line) == 1) { ... } to read the whole file line by line, you must consume the pending newline in the body of the loop and the loop would stop at the first empty line.

Example:

char line[100];
if (scanf("%99[^\n]", line) == 1) {
    /* handle input line */
} else {
    /* stream is at end of file or has an empty line */
}

这篇关于scanf() 函数中的扫描集有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆