【问题标题】:Continue running program until user type Ctrl + a继续运行程序,直到用户键入 Ctrl + a
【发布时间】:2011-01-01 05:42:53
【问题描述】:

我正在为考试练习 Linux 的 C 编程。 当用户按下 Ctrl + a (不是 Ctrl+c )时,我不知道如何退出程序 例如,循环某些内容直到用户按下 Ctrl+a 谁能告诉我如何检查 Ctrl+a 输入?

注意:我正在使用 'gcc' 并使用 './a.out' 运行输出

提前感谢大家!

【问题讨论】:

  • 标准 C 语言不支持键盘轮询,因此您必须使用特定于操作系统的东西。我添加了一个 linux 标签来表明这一点。
  • 旁注/一些处理密钥处理的 c 代码:retroforth.org/projects/darcs/TE/term.h
  • @Neil:除非你使用跨平台库

标签: c linux


【解决方案1】:

Turbo C 和其他 C 的 Windows 实现有一个函数调用 getch(),它可以从键盘读取单个字符;那些会做你想做的。

在 POSIX 环境中,例如在 Unix/Linux 下由 gcc 编译的程序实现,该功能并不直接存在。

有一个名为curses 的库,它允许C 程序进行全屏输出处理,并且curses 中还有getch() 功能。这可能最终成为您问题的最简单答案。您需要阅读有关 curses 的文档并将头文件和库链接到您的程序中。

【讨论】:

【解决方案2】:

对 Ctrl-C 有特殊支持,由系统翻译成信号。如果您希望您的程序在使用另一个特定组合键时立即停止,这将更加困难。

  • 您需要检查程序的标准输入,并且您需要设置标准输入以便输入不会被缓冲(否则在用户按下验证之前您将看不到任何输入“返回”)。后一部分将通过ioctl() 调用完成,并且不可移植;

  • 您将需要线程或轮询,这在 C 语言中都不是很好。

在 C 中练习比这些更有趣。

【讨论】:

  • 我不知道为什么投反对票。这个答案有问题吗?
  • 我也不知道为什么有人不赞成你。无论如何感谢您的回答:)
【解决方案3】:

catching ctrl-c event

这篇文章回答了你的问题

【讨论】:

    【解决方案4】:

    你在寻找这样的东西吗??? 该程序不会停止,因为您按 ctrl+A 并回车。

    #include <stdio.h>
    
    int main() {
        char a;
        while( a!=1 ) //Ascii code for ctrl + A == 1
        {
            a=getchar();
            printf("still looping ...\n");
        }
        printf( "HA! You pressed CTRL+A\n" );
        return 0;
    }
    

    但是如果你想在按下 ctrl+A 之后终止你的程序(之后不按回车键),你可以在这里:

    #include <stdio.h>
    #include <ncurses.h>
    
    int main() {
        char a;
        initscr();
        raw();
    
        while( a!=1 )
            a=getch();
    
        endwin();
        return 0;
    }
    

    要使用 GCC 编译第二个代码,请尝试以下命令:

    gcc -o program.o -lncurses program.cpp
    

    【讨论】:

    • 哦,非常感谢。当我按 Ctrl+a 时程序退出,但我没有收到消息“哈!你...” 一个问题是为什么程序退出,为什么当我按 Ctrl+a 时 'a' 等于 '1'?
    • 我认为这不是 OP 想要的。他的想法更像是一种检查来自 STDIN 的输入的非阻塞、异步方式。把它想象成 Ctrl-a 生成一个信号并在程序中处理。如果我错了,请纠正我:)
    • 控制字符返回一个 ASCII 码等于字母表中的位置 - 所以 Ctrl+A = 1, Ctrl+C = 3, Ctrl+M = 13(顺便说一句回车), Ctrl +G = 7(顺便说一下铃声或哔声)。
    【解决方案5】:

    这会做你想做的事:

    stty intr ^a
    ./a.out
    

    为了获得额外的功劳,请使用适当的库函数执行相当于“stty intr ^a”的操作,例如“man termios”。

    【讨论】:

    • 抱歉,Richard,我无法关注你 :( 我不是高级程序员。
    • stty(和 termios)可以做的是将中断字符从 control-C 更改为 control-A。
    • 解释它的作用会有所帮助;我可以说,但新手可能不会。我相信一个知道 100% 但可以沟通 10% 的人不如知道 50% 但可以沟通 90% 的人有用..
    • 理查德,我也不知道你为什么被否决。感谢您提出此替代方案。
    • 顺便问一下,我的回答中“ioctl()”应该是“tcsetattr()”吗?
    【解决方案6】:

    有人首先发布了以下适用于我的代码,但我不知道他为什么删除了他的答案。

    原文链接:http://www.c.happycodings.com/Gnu-Linux/code18.html

    #include <stdio.h>
    #include <unistd.h>  /* sleep(1) */
    #include <signal.h>
    
    void ex_program(int sig);
    
    int main(void) {
     (void) signal(SIGINT, ex_program);
    
     while(1)
      printf("sleeping .. ZZZzzzz ....\n"), sleep(1);
    
     return 0;
    }
    
    void ex_program(int sig) {
     printf("Wake up call ... !!! - Catched signal: %d ... !!\n", sig);
     (void) signal(SIGINT, SIG_DFL);
    }
    

    【讨论】:

    • 我已经删除了我的,因为我还不确定 CTRL+A 哪个信号是由 Ctrl+a 创建的。
    • ctrl+A和ctrl+a没有区别
    【解决方案7】:

    这是如何将 CTRL-A 设置为中断来中断进程。还要注意,调用 tcsetattr 后 CTRL-C 不会破坏它。

    #include <stdio.h>
    #include <termios.h>
    #include <unistd.h>
    
    int main(int argc, char* argv[]) {
        struct termios termios;
    
        if ( tcgetattr(0, &termios) != -1 ) {
            termios.c_cc[VINTR] = '\x01'; /* CTRL-A */
            if ( tcsetattr(0, 0, &termios) != -1 ) {
                printf("Ready. Press CTRL-A to break this program\n");
                while ( 1 ) {
                    printf("*\n");
                    sleep(1);
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-01-19
      • 1970-01-01
      • 2013-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      相关资源
      最近更新 更多