持续运行程序直到用户输入Ctrl + a。

4
我正在为Linux考试练习C编程。当用户按下Ctrl + a(而不是Ctrl + c)时,我不知道如何退出程序。例如,循环某些内容直到用户按下Ctrl + a。有人能告诉我如何检查Ctrl + a输入吗?
注:我正在使用“gcc”,并通过“./a.out”运行输出。
谢谢大家提前!

1
标准的C语言不支持键盘轮询,因此您需要使用特定于操作系统的内容。我已添加了Linux标签以指示此内容。 - anon
附注 / 一些处理按键的 C 代码:http://retroforth.org/projects/darcs/TE/term.h - miku
@Neil:除非你使用跨平台库。 - Draemon
7个回答

3
Turbo C和其他适用于Windows的C实现中有一个名为getch()的函数调用,它可以从键盘读取单个字符;这些可以满足您的需求。
在POSIX环境中,例如Unix/Linux下由gcc编译的程序,该功能并不存在。
有一个名为的库,允许C程序进行全屏输出处理,并且中也有getch()功能。这可能是您问题的最简单答案。您需要阅读关于curses的文档,并将头文件和库链接到您的程序中。


2

系统对Ctrl-C有特殊的支持,它会被转化为一个信号。如果你想让你的程序在使用其他特定键组合时立即停止,那就会更难。

  • 你需要检查程序的标准输入,并设置标准输入,使输入不缓冲(否则,直到用户按下“回车”键确认之前,你将看不到任何输入)。后者应该使用ioctl()调用完成,但这种方法并不可移植;

  • 你需要使用线程或轮询,但在C语言中,这两种方法都不太可取。

在C语言中还有更有趣的东西可以练习。


我不确定为什么有人踩了这个回答。这个答案有什么问题吗? - Pascal Cuoq
1
我也不知道为什么有人会给你负投票。无论如何,还是谢谢你的回答 :) - Devyn

2

1

你是不是在寻找类似这样的东西??? 只要按下Ctrl+A和Enter,这个程序就不会停止。

#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'? - Devyn
我认为这不是OP所寻找的。他的想法更像是一种非阻塞、异步的检查STDIN输入的方式。可以将其视为Ctrl-a生成信号并在程序中处理。如果我错了,请纠正我 :) - user108127
控制字符返回一个等于字母表中位置的ASCII代码 - 因此Ctrl+A = 1,Ctrl+C = 3,Ctrl+M = 13(这恰好是回车符),Ctrl+G = 7(这恰好是响铃或蜂鸣声)。 - PP.

1
这将实现你想要的功能:
stty intr ^a
./a.out

为了额外的学分,使用适当的库函数(例如“man termios”)执行“stty intr ^a”的等效操作。


抱歉 Richard,我不明白你的意思 :( 我不是高级程序员。 - Devyn
1
stty(和termios)可以做的是将中断字符从Control-C更改为Control-A。 - Richard Pennington
解释一下这个代码的作用会很有帮助;我能看懂,但是新手可能不行。我相信,一个只知道100%但只能传达10%的人并不像一个只知道50%但能传达90%的人那样有用。 - PP.
Richard,我也不知道为什么你被踩了。感谢你提出这个替代方案。 - Pascal Cuoq
顺便问一下,我的回答中的"ioctl()"应该改成"tcsetattr()"吗? - Pascal Cuoq
@PP:我认为如果你给别人一个好的提示,让他们自己解决问题,那么他们将会比直接给出答案学到更多。Devyn说这是为了考试。 - Richard Pennington

0

有人发布了以下代码,它对我有效,但我不知道为什么他删除了他的答案。

原始链接: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 会触发哪个信号。 - Adam Matan
ctrl+A 和 ctrl+a 之间没有区别。 - Michel Gokan Khan

0

这是如何将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);
            }
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接