当输入不匹配的字符串时,Scanf 在 while 循环中不起作用

2023-12-01

我正在使用一个名为的函数检查类型检查用户是否输入了有效的整数类型输入。例如,如果用户输入 15,它将打印valid15c 将打印无效。但是,如果用户仅输入字符串输入,例如ccccc,它会导致无限循环并且程序崩溃。我在下面添加了一些屏幕截图来显示输出。

int checkType(int input, char *c) {
  if (input == 2 and *c == '\n') {
    return 1;
  } else {
    return 0;
  };
}

int main(void) {
  int faces = 0;
  char c;
  int valid = 0;
  int input;

  while (valid == 0) {
    printf("Enter number of faces: ");
    input = scanf("%d%c", &faces, &c);
    valid = checkType(input, &c);
    printf(valid == 0 ? "not valid\n" : "valid\n");
  }
}

enter image description here

无限循环:

enter image description here


The scanf()函数族并不是真正为输入有问题的语法而设计的。

解决问题的常用方法是以一定会成功的方式读入所有输入,例如通过读取完整的行(而不是数字、类似单词的字符串或任何其他具有预期格式的内容)fgets()。 然后您可以尝试按预期格式解析该行表示字符串。 (您可以使用sscanf()如果失败,您可以忽略它并阅读下一行,或者尝试根据同一输入的替代允许格式进行解析。

相关的区别在于读取整行将成功并将其从输入流中删除。与此相反,如果语法失败,您的代码会在输入流中留下与预期语法不匹配的内容。因此,它当然会在读取循环的下一次迭代中再次失败。这就是导致你无限循环的原因。

详细地:

  • 将整行读入缓冲区,
    using fgets()以及将字符数限制为缓冲区大小的选项
  • 此时,所有行都从输入中删除(又名 stdin,又名输入流),
    这意味着即使读取的行与任何允许的格式不匹配,下一次读取也将获得新的输入,
    这是与尝试直接读取输入的相关区别scanf()
  • 从行缓冲区中,尝试根据允许的格式读取单独的值,
    using sscanf()并检查返回值
  • 如果成功的话,您已经填充了预期的变量(例如整数);
    您可以尝试扫描其他非格式覆盖的尾随输入(并像不正确的输入一样继续,即使行的开头与允许的格式匹配)
  • 如果不成功尝试不同的允许格式,
    using sscanf() again,
    来自同一行缓冲区,即使格式部分匹配,该行缓冲区也不会更改
  • 如果没有允许的格式与输入匹配,则需要考虑它不正确
  • 不正确的输入可以被忽略或可能导致程序中出现致命的解析错误,您的选择
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当输入不匹配的字符串时,Scanf 在 while 循环中不起作用 的相关文章

  • 使用 Unity 在构造函数中使用属性依赖注入

    好的 我在基类中定义了一个依赖属性 我尝试在其派生类的构造函数内部使用它 但这不起作用 该属性显示为 null Unity 在使用 container Resolve 解析实例后解析依赖属性 我的另一种选择是将 IUnityContaine
  • VB.NET 相当于 C# 属性简写吗?

    是否有与 C 等效的 VB NET public string FirstName get set 我知道你能做到 Public Property name As String Get Return name ToString End Ge
  • std::cout 和 std::wcout 有什么区别?

    在c 中 有什么区别std cout and std wcout 它们都控制流缓冲区的输出或将内容打印到控制台 或者它们只是相似吗 它们作用于不同的字符类型 std cout uses char作为字符类型 std wcout uses w
  • 使用Physics.Raycast 和Physics2D.Raycast 检测对象上的点击

    我的场景中有一个空的游戏对象 带有 2D 组件盒碰撞器 我将脚本附加到该游戏对象 void OnMouseDown Debug Log clic 但是当我点击我的游戏对象时 没有任何效果 你有什么想法 如何检测我的盒子碰撞器上的点击 使用光
  • C++ 中本地类中的静态成员变量?

    我知道我们不能宣布static本地类中的成员变量 但其原因尚不清楚 那么请问有人可以解释一下吗 另外 为什么我们不能访问非static函数内部定义的变量 内部已经定义了局部类 直接在局部类成员函数中 在下面给出的代码中 int main i
  • 推导指南中的引用和值之间的差异

    考虑类型A template
  • 如何为 C 分配的 numpy 数组注册析构函数?

    我想在 C C 中为 numpy 数组分配数字 并将它们作为 numpy 数组传递给 python 我可以做的PyArray SimpleNewFromData http docs scipy org doc numpy reference
  • 如何修复此错误“GDI+ 中发生一般错误”?

    从默认名称打开图像并以默认名称保存 覆盖它 我需要从 Image Default jpg 制作图形 将其放在 picturebox1 image 上并在 picurebox1 上绘制一些图形 它有效 这不是我的问题 但我无法保存 pictu
  • 将内置类型转换为向量

    我的 TcpClient 类接受vector
  • 互斥体实现可以互换(独立于线程实现)

    所有互斥体实现最终都会调用相同的基本系统 硬件调用吗 这意味着它们可以互换吗 具体来说 如果我使用 gnu parallel算法 使用openmp 并且我想让他们称之为线程安全的类我可以使用boost mutex用于锁定 或者我必须编写自己
  • 在 C# 中循环遍历文件文件夹的最简单方法是什么?

    我尝试编写一个程序 使用包含相关文件路径的配置文件来导航本地文件系统 我的问题是 在 C 中执行文件 I O 这将是从桌面应用程序到服务器并返回 和文件系统导航时使用的最佳实践是什么 我知道如何谷歌 并且找到了几种解决方案 但我想知道各种功
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • 如何将整数转换为 void 指针?

    在 C 中使用线程时 我面临警告 警告 从不同大小的整数转换为指针 代码如下 include
  • PlaySound 可在 Visual Studio 中运行,但不能在独立 exe 中运行

    我正在尝试使用 Visual Studio 在 C 中播放 wav 文件 我将文件 my wav 放入项目目录中并使用代码 PlaySound TEXT my wav NULL SND FILENAME SND SYNC 我按下播放按钮 或
  • 如何在 Blackberry Cascades 中显示具有特定号码的电话板

    我正在使用带有 C QT 和 QML 的 Blackberry Cascades 10 Beta 3 SDK 以及 Blackberry 10 Dev Alpha Simulator 和 QNX Momentics IDE 并且我正在尝试实
  • std::async 与重载函数

    可能的重复 std bind 重载解析 https stackoverflow com questions 4159487 stdbind overload resolution 考虑以下 C 示例 class A public int f
  • 如何从main方法调用业务对象类?

    我已将代码分为业务对象 访问层 如下所示 void Main Business object public class ExpenseBO public void MakeExpense ExpensePayload payload var
  • C++ 密码屏蔽

    我正在编写一个代码来接收密码输入 下面是我的代码 程序运行良好 但问题是除了数字和字母字符之外的其他键也被读取 例如删除 插入等 我知道如何避免它吗 特q string pw char c while c 13 Loop until Ent
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也
  • Linq-to-entities,在一个查询中获取结果+行数

    我已经看到了有关此事的多个问题 但它们已经有 2 年 或更长 的历史了 所以我想知道这方面是否有任何变化 基本思想是填充网格视图并创建自定义分页 所以 我还需要结果和行数 在 SQL 中 这将类似于 SELECT COUNT id Id N

随机推荐

  • 使用 PHP 将数据从 MySQL 下载到 csv 文件

    如何指定从数据库下载的文件 main php include databaseConnection php result mysql query SELECT FROM participants while row mysql fetch
  • 使用 Angular 登录 Twitter

    我正在尝试使用 angular2 实现 singin 功能 也请阅读官方文档从这里 但是没明白流程是怎么回事 我的问题是 访问第一步 即 outh token 的参数是什么 有没有任何教授流程的工作示例或最佳文章 我已经阅读了很多关于 SO
  • 将 JWT SecurityToken 传递给 WCF 客户端

    我需要根据用户名 密码身份验证生成并向客户端颁发令牌 我尝试了多种方法来解决这个问题 但所有方法都遇到了问题 我的第一个计划是在我的 WCF 端点上实施 WS Trust Issue 我找到的示例使用了以下方法 OperationContr
  • 有没有办法覆盖`{}`对象?

    我试图使我的程序中的所有哈希都是 ActiveSupport OrderedHash 我可以通过以下方式重写 Hash new 构造函数 Hash ActiveSupport OrderedHash but class仍然是哈希 def 给
  • 为什么不使用 ASP.NET 中的 GDI+

    有人告诉我 从 ASP NET 使用 GDI 是危险且未定义的 这是因为没有设备上下文的保证吗 有人可以解释一下吗 有哪些替代方案 这是MSDN来源 http msdn microsoft com en us library system
  • 当虚拟不起作用时

    目前我的 C 类中有一个奇怪的错误 我有一个 ActiveX 包装类 作为 wxWidgets 的一部分 我向其中添加了一个新的虚拟函数 我有另一个类继承自 ActiveX 类 wxIEHtmlWin 但是 ActiveX 类总是调用它自己
  • 显示无效的 SQL 类型:sqlKind = UNINITIALIZED 错误

    String s1 PasswordText4 getText String s2 ConfirmText4 getText String s3 NameText4 getText String s4 UsernameText4 getTe
  • boost::thread 数据结构大小太荒谬了?

    编译器 linux 上的 clang x86 64 我已经有一段时间没有编写任何复杂的低级系统代码了 而且我通常针对系统原语 Windows 和 pthreads posix 进行编程 所以 进出的事情已经从我的记忆中消失了 我正在与boo
  • VS Code typescript:自动实现接口

    我有一个打字稿界面 想自动实现它 我一直在环顾四周并根据这个计算器问题 and github问题 这个功能应该已经存在 但它对我不起作用 没有出现灯泡 如果接口没有必需的成员 则代码操作 快速修复将不会出现在类定义中 interface I
  • 为什么 scanf 中不需要地址运算符?

    为什么 std gt names firstName 不需要地址运算符 但是 stud gt studentid 中需要地址运算符吗 struct student struct char lastName 10 char firstName
  • adb logcat:增加最大消息长度

    似乎 logcat 截断了很长的日志消息 有没有办法防止这种情况 adb logcat g ring buffer is 64Kb 63Kb consumed max entry is 20480b max payload is 20460
  • 在unix中按文件大小排序

    我有一个 unix 文件 其中包含以下数据 35 ag 0 ca 22 0 K nt 43 8 G ct 90 0 M se 2 4 M ew 1 6 K et 0 er 0 dr 18 ld Output 43 8 G ct 90 0 M
  • 安装错误:INSTALL_FAILED_OLDER_SDK

    我是 Android 开发新手 我想首先获得Hello World应用程序正在运行 我正在使用 Eclipse IDE 和 Android 4 0 3 版本 15 SDK 我从教程网站复制了所有内容 但是当我尝试在virtual devic
  • CMake链接外部库

    首先 我是 CMake 的新手 我刚刚开始使用它 我想将外部库链接到我的项目 我使用我从中获取的代码CMake 维基 在文章末尾 这是我的 CMakeLists txt cmake minimum required VERSION 2 8
  • 如何使用检查器测试此应用实例? (没有 CoArbitrary 实例(验证 e0 [Char]))

    Checkers是一个可重用 QuickCheck 属性的库 特别是 标准类型类 如何编写一个检查器实例来测试我的验证应用实例是否有效 import Test QuickCheck import Test QuickCheck Checke
  • 如何使用 Postgresql 生成从当前日期算起的 52 周

    如何使用 postgresql 生成从当前日期算起的 52 周 例如 从 current date 即今天的日期 到 52 周 您可以使用生成系列它允许您定义范围 开始 停止 以及步骤间隔 例如 生成系列 开始日期 结束日期 stepBy
  • 如何将继承的小部件传递给整个 Material 应用程序

    所以我有一个继承的小部件 如下所示 class InheritedStateWidget extends StatefulWidget final Widget child InheritedStateWidget required thi
  • Selenium 2.53.5 httplib.BadStatusLine:''Python

    我正在尝试使用 Python 2 7 中的 Selenium 2 53 5 以在线表单自动注册序列号 该脚本已经运行了 2 个多月 但昨天我在运行它时开始收到错误 httplib BadStatusLine 有任何已知的修复方法吗 我读过前
  • 所有类方法都返回自动释放的对象吗?

    我正在重读 Mac OS X 的 Cocoa 编程 的前几章 作者指出其中之一NSCalendarDate的类方法返回一个自动释放的对象 我总是假设所有类方法都返回一个自动释放的对象 因为没有alloc涉及 是否有必须专门保留的类方法 Th
  • 当输入不匹配的字符串时,Scanf 在 while 循环中不起作用

    我正在使用一个名为的函数检查类型检查用户是否输入了有效的整数类型输入 例如 如果用户输入 15 它将打印valid15c 将打印无效 但是 如果用户仅输入字符串输入 例如ccccc 它会导致无限循环并且程序崩溃 我在下面添加了一些屏幕截图来