免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4065 | 回复: 4
打印 上一主题 下一主题

getchar()怎样用信号退出 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-03-10 10:14 |只看该作者 |倒序浏览
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/select.h>
#include <signal.h>
#include <termios.h>


struct termios ttyOldStats;             // 终端属性
bool change_command_mode()
{
        struct termios ttyState;
        ttyState = ttyOldStats;

        ttyState.c_lflag &= ~ICANON;
        ttyState.c_lflag &= ~ECHO;
        ttyState.c_cc[VMIN] = 1;
        ttyState.c_iflag &= ~ISIG;
        tcsetattr(0, TCSANOW, &ttyState);

        return true;
}

bool  change_input_mode()
{
        tcsetattr(0, TCSANOW, &ttyOldStats);
        return true;
}

bool ctrl_c = false;
void int_func(int sig)
{
        ctrl_c = true;
}






int main()
{
        int ch;                 /* 取得的字符 */

        tcgetattr(0, &ttyOldStats);
        change_command_mode();          /* 设置为命令模式,立即返回控制台输入 */

        signal(SIGINT, int_func);       /* ctrl-c 信号处理 */

        fd_set readset;
        struct timeval timeout = {1000, 1000};
        FD_ZERO(&readset);
        FD_SET(STDIN_FILENO, &readset);

        while(1){
                int temp;
                temp = select(STDIN_FILENO + 1, &readset, NULL, NULL, &timeout);
                if(temp > 0){
                        /* 有输入 */
                        ch = getchar();          /* 取得一个按键 */
                        printf("input char: %d\n", ch);
                }else{
                        /* 超时或错误 */
                        if(ctrl_c  == true){
                                printf("ctrl -c\n");
                                ctrl_c = false;
                         }
                }
        }
        change_input_mode();

        exit(0);
}
现在我想要的结果是按一个建打印这个建的值,按ctrl-c打印“ctrl-c”,
上面实用select阻塞io,好象不可以

但是我去掉select,直接用getchar如果ctrl-c之后不会返回,getchar改为read函数也不会返回,
请问怎么实现这个功能,谢谢?

论坛徽章:
0
2 [报告]
发表于 2006-03-10 14:01 |只看该作者
我没有太明白你的意思
下面是我改的,不知合不合你的意思。


  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <sys/select.h>
  6. #include <signal.h>
  7. #include <termios.h>

  8. static volatile sig_atomic_t ctrl_c = 0; /* 临界资源 */
  9. struct termios ttyOldStats;             /*  终端属性 */

  10. void change_command_mode()
  11. {
  12.     struct termios ttyState;
  13.     ttyState = ttyOldStats;

  14.     ttyState.c_lflag &= ~ICANON;
  15.     ttyState.c_lflag &= ~ECHO;
  16.     ttyState.c_cc[VMIN] = 1;
  17.     ttyState.c_iflag &= ~ISIG;
  18.     tcsetattr(0, TCSANOW, &ttyState);

  19.     return;
  20. }

  21. void change_input_mode()
  22. {
  23.     tcsetattr(0, TCSANOW, &ttyOldStats);
  24.     return;
  25. }

  26. void int_func(int sig)
  27. {
  28.      ctrl_c = 1;
  29. }


  30. int main()
  31. {
  32.     int ch;                 /* 取得的字符 */

  33.     tcgetattr(0, &ttyOldStats);
  34.     change_command_mode();          /* 设置为命令模式,立即返回控制台输入 */


  35.     while(1){
  36.                 signal(SIGINT, int_func);       /* ctrl-c 信号处理 */
  37.                 if(!ctrl_c){
  38.                         /* 有输入 */
  39.                         ch = getchar();          /* 取得一个按键 */
  40.                         printf("input char: %c(%d)\n", ch, ch);
  41.                 }else if(ctrl_c  == 1) {
  42.                         printf("ctrl -c\n");
  43.                         ctrl_c = 0;
  44.                 } else {
  45.                         printf("error: ctrl_c is an unexpected variable\n");
  46.                         break;
  47.                 }
  48.     }
  49.     change_input_mode();

  50.     return 0;
  51. }
复制代码




[ 本帖最后由 westgarden 于 2006-3-10 14:08 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2006-03-12 14:04 |只看该作者
static volatile sig_atomic_t ctrl_c = 0; /* 临界资源 */

2楼,请问一下,这个定义是什么意思呢。。不好意思,我没看明白volatile sig_atomic中volatile 是什么类型,用来做什么啊?

都在什么时候用啊?谢谢

论坛徽章:
0
4 [报告]
发表于 2006-03-12 18:46 |只看该作者
static volatile sig_atomic_t doneflag = 0;

限定符volatile通知编译器,变量ctrl_c的修改可能会异步于程序的执行。



以下摘自《关于volatile关键字的说明以及测试 》一文


volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如
操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行
优化,从而可以提供对特殊地址的稳定访问。

使用该关键字的例子如下:

int volatile nVint;

当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指
令刚刚从该处读取过数据。而且读取的数据立刻被保存。

例如:

volatile int i=10;
int a = i;
。。。//其他代码,并未明确告诉编译器,对i进行过操作
int b = i;

volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的
汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间
的代码没有对i进行过操作,它会自动把上次读的数据放在b中。而不是重新从i里面读。这样以来,如果
i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问。

论坛徽章:
0
5 [报告]
发表于 2006-03-14 19:32 |只看该作者
to westgarden :多谢你的答复,不过我想要的是ctrl-c立即从getchar退出而取得信号,
上面的程序只能在下次getchar之后取得信号。

thanks all
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP