如何防止 scanf() 永远等待输入字符?

2023-12-08

我想在控制台应用程序中完成以下任务:

  1. 如果用户输入一个字符,应用程序将执行以下操作 相应的任务。例如,如果用户输入1, 该程序 如果用户输入,将执行任务 1q,程序将退出;
  2. 如果用户没有输入任何内容,程序将每隔10秒执行一次默认任务(时间不必很严格)。

这是我的代码:

#include <stdio.h>
#include <time.h>

char buff[64];
char command;

while(command != 'q')
{
   begin:
   printf(">> ");
   scanf("%s", buff);
   command = buff[0];

   switch (command)
   {
       case '1':
       // task 1 code will be added here;
          break;
       case '2':
       // task 2 code will be added here;
          break;
       case 'q':
          printf("quit the loop.\n");
          break;
   }

   // wait for 10 seconds;
   Sleep(10000);
   // default task code will be added here;

  if(command != 'q')
  {
     goto begin;
  }

}

但问题是程序会陷入scanf()如果没有输入字符,则函数永远等待输入字符。所以我想知道如何跳过scanf()一定时间后,我的意思是,例如,如果1秒后没有输入,程序可以继续执行,从而完成上面列出的第二件事。

如果重要的话,平台是Windows。

I've removed the semicolon after the while() it was an obvious mistake.


尝试使用 select() 函数。然后你可以等待 10 秒,直到你可以从 stdin 读取而不会阻塞。如果 select() 返回零,则执行默认操作。 我不知道这是否适用于 Windows,这是 POSIX 标准。如果你碰巧在unix/linux上开发,请尝试man select

我刚刚使用 select 编写了一个工作示例:

#include <stdlib.h>
#include <stdio.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#define MAXBYTES 80

int main(int argc, char *argv[])
{
        fd_set readfds;
        int    num_readable;
        struct timeval tv;
        int    num_bytes;
        char   buf[MAXBYTES];
        int    fd_stdin;

        fd_stdin = fileno(stdin);

        while(1) {
                FD_ZERO(&readfds);
                FD_SET(fileno(stdin), &readfds);

                tv.tv_sec = 10;
                tv.tv_usec = 0;

                printf("Enter command: ");
                fflush(stdout);
                num_readable = select(fd_stdin + 1, &readfds, NULL, NULL, &tv);
                if (num_readable == -1) {
                        fprintf(stderr, "\nError in select : %s\n", strerror(errno));
                        exit(1);
                }
                if (num_readable == 0) {
                        printf("\nPerforming default action after 10 seconds\n");
                        break;  /* since I don't want to test forever */
                } else {
                        num_bytes = read(fd_stdin, buf, MAXBYTES);
                        if (num_bytes < 0) {
                                fprintf(stderr, "\nError on read : %s\n", strerror(errno));
                                exit(1);
                        }
                        /* process command, maybe by sscanf */
                        printf("\nRead %d bytes\n", num_bytes);
                        break; /* to terminate loop, since I don't process anything */
                }
        }

        return 0;
}

注意:下面的 poll() 示例也可以,没有问题。对于其余部分,我选择将可用字节读入缓冲区(最多 MAXBYTES)。之后可以对其进行扫描。 (scanf() 只是不太适合我的朋友,但这是个人品味问题)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何防止 scanf() 永远等待输入字符? 的相关文章

随机推荐

  • 在 Kubernetes cron 作业中运行的应用程序无法连接到同一 Kubernetes 集群中的数据库

    我有一个 Kubernetes 集群 运行 PostgreSQL 数据库 Grafana 仪表板和一个在 Kubernetes 内每小时运行的 Python 单运行应用程序 构建为 Docker 映像 CronJob 见下面的清单 此外 这
  • 如何检查字符串是否包含字母表中的任何字母?

    检查字符串是否包含字母表中的任何字母的最佳纯 Python 实现是什么 string 1 555 555 5555 string 2 555 555 5555 ext 5555 Where string 1会回来False因为其中没有字母表
  • 循环分割大数据帧并在 R 中写入多个 CSV 文件 [重复]

    这个问题在这里已经有答案了 我有一个包含 2500 万行的文件 需要根据因子级别将其拆分为更小的文件 我创建了一个数据框来包含不同的因子级别 并编写了一个循环来执行一些操作并写出一个csv 数据看起来像这样 Country Col2 Cod
  • 在 WinForms 线程上使用 CoInitializeEx

    我正在为 DSLR 相机开发一个 SDK 其中包含以下说明 开发Windows应用程序的注意事项 创建应用程序时 在 Windows 下运行的每个程序都需要 COM 初始化 线程以便从主线程以外的线程访问相机 线 创建用户线程并从中访问相机
  • 两个或多个带进度的前台通知在更新其进度时相互替换

    我有一项服务将在前台运行上传任务 然后在通知中显示进度 由于用户可能会使用不同的 id 请求多次上传 因此将运行两个或多个前台服务 一切正常 但我想要的是使用此代码显示所有任务的通知和进度 NotificationCompat Builde
  • 使用关联实体的正确方法是什么?

    这是描述 绘制 Poke Hospital 的实体关系图 其中提供 为神奇宝贝提供医疗服务 每个神奇宝贝都会与其中一位护士乔伊有个约会 在 除了记录每个神奇宝贝的名称 类型和训练师之外 系统需要跟踪多种类型的疾病 诊断为神奇宝贝 在预约期间
  • 是否可以避免实现文件中重复类名?

    有没有办法避免Graph 在实现文件中重复 但仍然将类拆分为标头 实现 如 头文件 ifndef Graph H define Graph H class Graph public Graph int n void printGraph v
  • 谷歌云端硬盘托管 URL 发生变化

    我开发了一个网络应用程序 使用谷歌驱动器作为托管平台 如下所述 https support google com drive answer 2881970 hl en 当用户访问时 应用程序一直运行正常 但昨天它开始将该地址重定向到 b21
  • 如何获取两个地点之间的行驶距离?

    我在我的应用程序中使用 GoogleMapv2 api 我想绘制一条从源到目的地的多边形线 并在地图活动上显示旅行时间和距离 但我无法找到它 请帮我 我的代码片段在这里 public class NavigationActivity ext
  • 为什么新的网络版 Dropbox 可以在不刷新页面的情况下更改 URL? [复制]

    这个问题在这里已经有答案了 可能的重复 如何在不离开页面的情况下更改浏览器中显示的 URL 如何像 GitHub 一样进行出色的无刷新页面更改 更改浏览器 URL 和页面内容 无需重新加载且无需使用片段 太神奇了 新的 Dropbox 网页
  • Win32 和 Win64 机器中的 SendInput 按键

    我在 xp 32 位下使用 sendInput 使用 web 服务来推送当前焦点窗口的 F 5 现在在 Vista win64 下我无法获得这个结果 有些文章指出使用 4 位或 8 位的 uint 问题 但这并不能通过差异编译和 Field
  • 求二叉树的直径

    我试图在java中找到二叉树的直径 包含最大节点数的树中任意两个节点之间的路径长度 我的代码片段 public int diametre Node node int d if node null return 0 lh diametre n
  • 使用正确的 pack:// URI 格式

    我有一个 WPF 类库 其中包含一个包含图像的文件夹 图像 在 WPF 应用程序中 我不会使用以下方式引用该文件夹中的图像
  • 在哪里可以找到要添加为参考的 Microsoft.VisualStudio.ExtensionManager?

    我想在使用 VS2013 SDK 安装的 VS2013 中的控制台应用程序上添加以下引用 Microsoft VisualStudio ExtensionManager Microsoft VisualStudio ExtensionMan
  • Xcode 6.1 文件中缺少所需的架构 X86_64

    在 Xcode 6 1 中 我收到 iPhone 6 iPhone 5s iOS 7 1 的错误 其中显示 Undefined symbols for architecture x86 64 OBJC CLASS ClientAuthent
  • 如何在画布上制作弹跳球的动画

    你好 我刚刚开始编写 Java 和 HTML 等代码 所以有时我会遇到困难 因此 我加入 StackOverflow 寻求您的帮助 请对我好一点 我正在尝试使用动画setInterval 并绘制方法来创建一个弹跳球 该球在每帧中移动多个像素
  • OPENCV waitKey()方法返回类型

    我正在尝试使用在线教程学习 OPENCV 用于图像处理项目 opencv 文档说 waitKey 返回一个 int 这应该是按下的键的 ASCII 值 但大多数在线教程都使用以下代码 可以正常编译和运行 if char 27 waitKey
  • Python XML 解析和 getElementsByTagName

    我试图解析以下 xml 并围绕我的业务需求获取我感兴趣的特定标签 我想我做错了什么 不知道如何解析我所需的标签 想要利用 pandas 以便我可以进一步过滤细节 学弟学妹们多多支持 我的 XML 来自 URI
  • Clojure core.logic CLP(FD) 投影 FD 变量

    我正在使用 Clojure 的 core logic CLP FD 库 core logic 版本 0 8 3 开发一种简单的方形打包算法 正方形表示如下 x11 y11 x12 y12 x21 y21 x22 y22 每个正方形表示为其左
  • 如何防止 scanf() 永远等待输入字符?

    我想在控制台应用程序中完成以下任务 如果用户输入一个字符 应用程序将执行以下操作 相应的任务 例如 如果用户输入1 该程序 如果用户输入 将执行任务 1q 程序将退出 如果用户没有输入任何内容 程序将每隔10秒执行一次默认任务 时间不必很严