• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 各位大佬請幫忙看看我的程序問題出在哪里? 請不吝賜教!

    發表于:2007-05-25來源:作者:點擊數: 標簽:程序各位大佬幫忙看看
    我寫了一個程序,希望用戶從鍵盤輸入一個字符[getchar()],如果5秒鐘過去了,用戶仍未輸入字符,則繼續執行getchar()后的代碼,但我的程序卻始終在等待鍵盤輸入,如沒有輸入,則無法執行到后面的代碼,請各位大佬看看問題出在哪里? 請不吝賜教?。?! 我的程

    我寫了一個程序,希望用戶從鍵盤輸入一個字符[getchar()],如果5秒鐘過去了,用戶仍未輸入字符,則繼續執行getchar()后的代碼,但我的程序卻始終在等待鍵盤輸入,如沒有輸入,則無法執行到后面的代碼,請各位大佬看看問題出在哪里?  
    請不吝賜教?。?!

    我的程序如下:



    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <signal.h>

    #define TIMEOUT 5
    void sigProcess(int);
    main(void)
    {
       printf("The program is about to get a character from the keyboard:\n");
       alarm(TIMEOUT);
       signal(SIGALRM,sigProcess);
       getchar();
       
       ...........                  /* here goes the code if timeout */

    }

    void sigProcess(int signo)
    {
      signal(SIGALRM,SIG_DFL);
      printf("In the signal process function: TIMEOUT\n");
    }

     Alligator27 回復于:2005-04-09 01:25:48
    getchar()是blocking函數. 你要non-blocking函數.

    window: kbhit()
    unix: 這個函數simulator
    http://www.pwilson.net/kbhit.html

    /* ***************************************************************************
     *
     *          Copyright 1992-2005 by Pete Wilson All Rights Reserved
     *           50 Staples Street : Lowell Massachusetts 01851 : USA
     *        http://www.pwilson.net/   pete@pwilson.net   +1 978-454-4547
     *
     * This item is free software: you can redistribute it and/or modify it as 
     * long as you preserve this copyright notice. Pete Wilson prepared this item 
     * hoping it might be useful, but it has NO WARRANTY WHATEVER, not even any 
     * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
     *
     *************************************************************************** */

    /* ***************************************************************************
     *
     *                          KBHIT.C
     *
     * Based on the work of W. Richard Stevens in "Advanced Programming in
     *   the Unix Environment," Addison-Wesley; and of Floyd Davidson. 
     *
     * Contains these functions:
     *
     *  To set the TTY mode:
     *     tty_set_raw() Unix setup to read a character at a time.
     *     tty_set_cooked() Unix setup to reverse tty_set_raw()
     *
     *  To read keyboard input:
     *     kb_getc()      keyboard get character, NON-BLOCKING. If a char
     *                      has been typed, return it. Else return 0.
     *     kb_getc_w()    kb get char with wait: BLOCKING. Wait for a char
     *                      to be typed and return it.
     *
     *  How to use:
     *     tty_set_raw()  set the TTY mode to read one char at a time.
     *     kb_getc()      read chars one by one.
     *     tty_set_cooked() VERY IMPORTANT: restore cooked mode when done.
     *
     * Revision History:
     *
     *     DATE                  DESCRIPTION
     * -----------    --------------------------------------------
     * 12-jan-2002     new
     * 20-aug-2002     cleanup
     *
     * Notes:
     * -----------    --------------------------------------------
     * 25-nov-2003     notate anomoly in some Unices: termattr.c_clearcase/" target="_blank" >cc[VMIN] = 0;
     *************************************************************************** */

    #ifdef __cplusplus
      extern "C" {
    #endif

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <termios.h>
    #include <unistd.h>
    #include <errno.h>

    #ifndef STDIN_FILENO
      #define STDIN_FILENO 0
    #endif

    extern int errno;                 

    static struct termios termattr, save_termattr;
    static int ttysavefd = -1;
    static enum 

      RESET, RAW, CBREAK 
    } ttystate = RESET;

    /* ***************************************************************************
     *
     * set_tty_raw(), put the user's TTY in one-character-at-a-time mode.
     * returns 0 on success, -1 on failure.
     *
     *************************************************************************** */
    int
    set_tty_raw(void) 
    {
      int i;

      i = tcgetattr (STDIN_FILENO, &termattr);
      if (i < 0) 
      {
        printf("tcgetattr() returned %d for fildes=%d\n",i,STDIN_FILENO); 
        perror ("");
        return -1;
      }
      save_termattr = termattr;

      termattr.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
      termattr.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
      termattr.c_cflag &= ~(CSIZE | PARENB);
      termattr.c_cflag |= CS8;
      termattr.c_oflag &= ~(OPOST);
       
      termattr.c_cc[VMIN] = 1;  /* or 0 for some Unices;  see note 1 */
      termattr.c_cc[VTIME] = 0;

      i = tcsetattr (STDIN_FILENO, TCSANOW, &termattr);
      if (i < 0) 
      {
        printf("tcsetattr() returned %d for fildes=%d\n",i,STDIN_FILENO); 
        perror("");
        return -1;
      }
       
      ttystate = RAW;
      ttysavefd = STDIN_FILENO;

      return 0;
    }

    /* ***************************************************************************
     *
     * set_tty_cbreak(), put the user's TTY in cbreak mode.
     * returns 0 on success, -1 on failure.
     *
     *************************************************************************** */
    int 
    set_tty_cbreak() 
    {
      int i;

      i = tcgetattr (STDIN_FILENO, &termattr);
      if (i < 0) 
      {
        printf("tcgetattr() returned %d for fildes=%d\n",i,STDIN_FILENO); 
        perror ("");
        return -1;
      }

      save_termattr = termattr;

      termattr.c_lflag &= ~(ECHO | ICANON);
      termattr.c_cc[VMIN] = 1;
      termattr.c_cc[VTIME] = 0;
          
      i = tcsetattr (STDIN_FILENO, TCSANOW, &termattr);
      if (i < 0) 
      {
        printf("tcsetattr() returned %d for fildes=%d\n",i,STDIN_FILENO); 
        perror ("");
        return -1;
      }
      ttystate = CBREAK;
      ttysavefd = STDIN_FILENO;

      return 0;
    }

    /* ***************************************************************************
     *
     * set_tty_cooked(), restore normal TTY mode. Very important to call
     *   the function before exiting else the TTY won't be too usable.
     * returns 0 on success, -1 on failure.
     *
     *************************************************************************** */
    int
    set_tty_cooked() 
    {
      int i;
      if (ttystate != CBREAK && ttystate != RAW) 
      {
        return 0;
      }
      i = tcsetattr (STDIN_FILENO, TCSAFLUSH, &save_termattr);
      if (i < 0) 
      {
        return -1;
      }
      ttystate = RESET;
      return 0;
    }

    /* ***************************************************************************
     *
     * kb_getc(), if there's a typed character waiting to be read,
     *   return it; else return 0.
     *
     *************************************************************************** */
    unsigned char
    kb_getc(void) 
    {
      unsigned char ch;
      ssize_t size;

      size = read (STDIN_FILENO, &ch, 1);
      if (size == 0)
      {
        return 0;
      }
      else
      {
        return ch;
      }
    }

    /* ***************************************************************************
     *
     * kb_getc_w(), wait for a character to be typed and return it.
     *
     *************************************************************************** */
    unsigned char
    kb_getc_w(void) 
    {
      unsigned char ch;
      size_t size;

      while (1)
      {

        usleep(20000);        /* 1/50th second: thanks, Floyd! */

        size = read (STDIN_FILENO, &ch, 1);
        if (size > 0)
        {
          break;
        }
      }
      return ch;
    }


    #define TEST
    #ifdef TEST

    void echo(unsigned char ch);

    static enum 

      CH_ONLY, CH_HEX 
    } how_echo = CH_ONLY;

    int 
    main(int argc, char * argv[])
    {
      unsigned char ch;

      printf("Test Unix single-character input.\n");

      set_tty_raw();         /* set up character-at-a-time */
      
      while (1)              /* wait here for a typed char */
      {
        usleep(20000);       /* 1/50th second: thanks, Floyd! */
        ch = kb_getc();      /* char typed by user? */
        if (0x03 == ch)      /* might be control-C */
        {
          set_tty_cooked();  /* control-C, restore normal TTY mode */
          return 1;          /* and get out */
        }
        echo(ch);            /* not control-C, echo it */
      }
    }

    void
    echo(unsigned char ch)
    {
      switch (how_echo)
      {
      case CH_HEX:
        printf("%c,0x%x  ",ch,ch);
        break;
      default:
      case CH_ONLY:
        printf("%c", ch);
        break;
      }

      fflush(stdout);      /* push it out */
    }

    #endif /* test */


    #ifdef __cplusplus
    }
    #endif


    /* ----- Notes -----

    1. Some flavors of Unix need termattr.c_cc[VMIN] = 0 here else the read() in kb_getc() blocks:

    -- MPC7400 G4 MAC running Yellowdog Linux with a 2.4.18 Kernel. Thanks to Jon Harrison.

    ----- */

     bleem1998 回復于:2005-04-09 15:24:07
    好長阿
    我覺得用一個select就可以解決5秒的問題
    如果想直接接收到鍵盤字符而不用回車來確認
    用一個tcsetattr也解決了

     dzbjet 回復于:2005-04-10 16:13:06
    你不會再信號處理函數中發送一個自定義的控制字符給getchar(),然后判斷一下,如果是你發送的控制字符,就說明是超時,。。。。。。。。

     zi_ji 回復于:2005-04-10 16:29:16
    我覺得把signal放在alarm上面就行

     spirn 回復于:2005-04-20 01:28:48
    原來不行的原因是即使超時,最后還是跑回getchar里面去,所以程序無論怎么超時都會停在哪里
    不過在同一個進程內部用這種方式不好。例如在getchar的內部分配了一些資源,然后由于超時強行恢復堆棧跳出來,那之前已經分配的資源就沒有人釋放了。所以除非你確定timeout會跳過的代碼里面不會導致資源泄漏,否則就不要在同一個進程內部用這種機制

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <signal.h>
    #include <setjmp.h>

    #define TIMEOUT 5
    void sigProcess(int);
    static jmp_buf env;
    main(void)
    {
        int ret ;
        printf("The program is about to get a character from the keyboard:\n");
        alarm(TIMEOUT);
        signal(SIGALRM,sigProcess);

        if ((ret=setjmp(env))==0){
                getchar();
                alarm(0) ; //注意保護
                printf("haha\n");
                return 0 ;
        }
        alarm(0) ;//這是一個好習慣
        printf("ret=%d\n",ret);
    }

    void sigProcess(int signo)
    {
        signal(SIGALRM,SIG_DFL);
        printf("In the signal process function: TIMEOUT\n");
        longjmp(env, 5);
    }

    原文轉自:http://www.kjueaiud.com

    評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>