在读取 C 中的字符时打印



我正在尝试编写一小段代码来响应箭头键。我知道 up 由 ^[[A] 表示,我有以下代码来检查该序列:

     while( 1 )
     {
         input_char = fgetc( stdin );
         if( input_char == EOF || input_char == 'n' )
         {
             break;
         }
         /* Escape sequence */
         if( input_char == 27 )
         {
             input_char = getc( stdin );
             if( input_char == '[' )
             {
                 switch( getc( stdin ) )
                 {
                     case 'A':
                     printf("Move upn");
                     break;
                 }
             }
         }
     }

每当我按"向上"时,转义序列 (^[[A) 都会出现在屏幕上,但在我按回车键之前不会出现"向上移动"。

最终目标是用其他一些数据替换当前行上的文本,所以我尝试这样做

printf("r%s", "New Text");

代替"上移",但在按下 Enter 之前它仍然不显示。

我阅读字符的方式有问题吗?

谢谢!

编辑 快速说明,它适用于 *nix 系统。

溶液谢谢大家的指点。我选择了stepanbujnak的解决方案,因为它相当简单。我注意到的一件事是,修改字符串(退格等)的键的许多行为与您预期的不同。它将通过在线的任何内容(包括 printf'd 的东西)退格,我必须考虑到这一点。在那之后,让其他人排队也不错:)

stdin是行缓冲的,因此getc(stdin)fgetc(stdin)在按 Enter 之前看不到这些字符 有关更多详细信息,请参阅此链接

编辑:如果您不想进入ncurses还有其他有用的方法,例如将终端设置为原始模式等来克服此限制。检查这个不错的SO帖子

从标准输入中捕获字符,无需等待按回车

您实际上只需要使用 termios 禁用线路缓冲

下面是执行此操作的示例:

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
int main() {
  struct termios old_term, new_term;
  char c;
  /* Get old terminal settings for further restoration */
  tcgetattr(0, &old_term);
  /* Copy the settings to the new value */
  new_term = old_term;
  /* Disable echo of the character and line buffering */
  new_term.c_lflag &= (~ICANON & ~ECHO);
  /* Set new settings to the terminal */
  tcsetattr(0, TCSANOW, &new_term);
  while ((c = getchar()) != 'q') {
    printf("You pressed: %cn", c);
  }
  /* Restore old settings */
  tcsetattr(0, TCSANOW, &old_term);
  return 0;
}

查看用于捕获转义序列(如箭头键)的curses库。

http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/keys.html

在大多数系统上,键(如箭头键、主页、向上翻页、中断等)是转义键,它们使用转义序列来辨别自己。 类似于 0x1B + Sequence,如果要捕获原始数据,则需要直接从文件描述符读取输入并侦听序列。 另一种方法是使用ncurses。

除了使用curses之外,下面说明了如何使用系统调用(例如read

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
    int fd = 0x0; /* STDIN */
    size_t bytes_read;
    char buf[12];
    bytes_read = read(fd, buf, 3);
    printf("%02x %02x %02xn", buf[0], buf[1], buf[2]);
    return 0;
}

按 UP 后输出

Lukes-ASA-Macbook:tmp luke$ gcc -o out test.c
Lukes-ASA-Macbook:tmp luke$ ./out
^[[A
1b 5b 41

这应该让你上路。

您可以缓冲输入以查找0x1b,然后启用分析标志以查找字符的转义序列,而不是单个字符分析。

相关内容

  • 没有找到相关文章

最新更新