Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.

C / UNIX realtime key-press detectie

Pagina: 1
Acties:

  • blorf
  • Registratie: December 2003
  • Laatst online: 22-08 16:22
Ziehier het volgende C programmaatje voor de unix console. Het dumpt een tekstbestand op het scherm en laat de letters in kleuren knipperen mbv ncurses. Het probleem is dat ik eigenlijk wil dat het programma blijft lopen totdat er op een toets gedrukt wordt. Normaalgesproken kun je getch() gebruiken om letter voor letter toetsenbord input te lezen, maar getch() stopt alles vrolijk en gaat wachten op stdin actie.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <stdio.h>
#include <ncurses.h>

main()
{
  FILE *bestand;
  int Kleur = 0, Regel[1000], Kolom[1000], Tel = 0, RegTel = 0, KolTel = 0, Getal, i;
  char Let = 0, Letter[1000];
  bool Toets = false;

  bestand = fopen ("ascii.txt", "rt");           // letters laden, coords onthouden.
  do
  {
    Let = fgetc(bestand);
    if ( Let != 10 )
    {
      Letter[Tel] = Let;
      Regel[Tel] = RegTel;
      Kolom[Tel]= KolTel;
      KolTel++;
      if ( Let != 32 ) Tel++;
    }
    else
    {
      RegTel++;
      KolTel = 0;
    }
  }
  while (Let != EOF);

  initscr();                                     // start ncurses scherm
  curs_set(0);                                   // hide cursor
  noecho();                                      // geen echo van toetsenbord naar scherm
  start_color();
  cbreak();                                      // niet wachten op enter na toetsenbord input
  for ( i = 0; i <=7; i++) init_pair(i, i, 0);   // curses kleuren init

  while ( ! Toets )
  {
    init_color(rand()%7+1, rand()%1000, rand()%1000,rand()%1000);
    Kleur=rand()%7+1;
    attron(COLOR_PAIR(Kleur));
    Getal = rand()%(Tel-1);
    mvaddch(Regel[Getal],Kolom[Getal],Letter[Getal]);
    attroff(COLOR_PAIR(Kleur));
    refresh();
    usleep(9999); // niet teveel cpu weggeven

//    hier moet iets komen dat kijkt of er op een toets is gedrukt.
//    if ( getch() ) Toets = true  werkt niet, dan stopt het programma om te wachten op toets.

  }
  endwin();
}

Met een shell script constructie kan ik dit waarschijnlijk wel voor elkaar krijgen door tty's te redirecten ofzo, maar das niet de mooie manier.

edit: hee er zaten spaties vooraan. Is daar een opmaak truukje voor? ja dus

[ Voor 4% gewijzigd door blorf op 24-07-2008 16:30 ]

You are in a maze of little twisting passages, all different.


  • Cassettebandje
  • Registratie: Juli 2002
  • Laatst online: 17:04

Cassettebandje

SA-C90 TDK

Als je de code-tag gebruikt dan gaat de opmaak ook goed. Als je de getch manpage leest staat daar "In no-delay mode, if no input is waiting, the value ERR is returned." Als je googled op no-delay mode en ncurses dan kom je uit op de nodelay functie.
Succes!

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 01-11 22:03

leuk_he

1. Controleer de kabel!

Met poll / select kijken of er input staat?

lees ook:

http://www.is.pku.edu.cn/~qzy/c/c_faq/c-faq19.txt (unix buffert per regel wat je dus wellicht uit wil zetten)

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


  • blorf
  • Registratie: December 2003
  • Laatst online: 22-08 16:22
De cbreak() is om dat linebufferen uit te zetten, maar ik ben er uit, springuin had gelijk.
nodelay() werkt, ik wist alleen niet dat ik stdscr moest gebruiken ipv 0
daarom dacht ik dat mijn prog te snel ging om een toets te onderscheppen.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <ncurses.h>
main()
{
  char Toets = ERR;
  initscr();
  noecho();
  cbreak();
  nodelay(stdscr, true);
  addstr ("druk op <esc>...");
  while (Toets != 27)
  {
    usleep(99999);
    addch('.');
    Toets = getch();
  }
  endwin();
}

You are in a maze of little twisting passages, all different.


  • Niekk
  • Registratie: September 2007
  • Laatst online: 12-04-2021

Niekk

Human-readable is relatief

Hmm. Bedoel je niet dat je geowon wilt lezen "wanneer je het wilt" ?
oftewel: Non-blocking ? Ik weet niet of het kan met stdin, maar je kan proberen dit op non-blocking te setten. Dan wordt er niet geblockt op je call