首页 > 解决方案 > 我可以使用什么来进行输入转换而不是 scanf?

问题描述

我经常看到有人劝阻他人使用scanf并说有更好的选择。但是,我最终看到的只是“不要使用scanf“这是一个正确的格式字符串” ,而从来没有提到任何“更好的选择”的例子。

例如,让我们看一下这段代码:

scanf("%c", &c);

这将读取上次转换后留在输入流中的空白。通常建议的解决方案是使用:

scanf(" %c", &c);

或不使用scanf.

既然scanf不好,那么有哪些 ANSI C 选项可以转换scanf通常可以在不使用的情况下处理的输入格式(例如整数、浮点数和字符串)scanf

标签: cscanf

解决方案


最常见的读取输入的方法是:

  • 使用fgets固定大小,这是通常建议的,并且

  • using fgetc,如果您只阅读单个char.

要转换输入,您可以使用多种函数:

  • strtoll, 将字符串转换为整数

  • strtof// d,ld将字符串转换为浮点数

  • sscanf,这并不简单地使用那么糟糕scanf,尽管它确实有下面提到的大部分缺点

  • 没有很好的方法来解析纯 ANSI C 中分隔符分隔的输入。要么使用strtok_rPOSIX 或strtok,这不是线程安全的。您还可以使用and滚动您自己的线程安全变体,因为它不涉及任何特殊的操作系统支持。strcspnstrspnstrtok_r

  • 这可能有点矫枉过正,但您可以使用词法分析器和解析器(flex并且bison是最常见的示例)。

  • 无需转换,只需使用字符串


由于我没有详细说明为什么 scanf我的问题不好,我将详细说明:

  • 使用转换说明符%[...]and %cscanf不会占用空格。正如这个问题的许多重复所证明的那样,这显然并不广为人知。

  • &在引用scanf的参数(特别是字符串)时,何时使用一元运算符存在一些混淆。

  • 很容易忽略scanf. 这很容易导致读取未初始化变量的未定义行为。

  • 很容易忘记防止scanf. scanf("%s", str)和 . 一样糟糕,如果不比gets.

  • 使用 转换整数时无法检测到溢出scanf事实上,溢出会导致这些函数出现未定义的行为



推荐阅读