1
votes

Pourquoi INPUT $ et INKEY $ ne fonctionnent-ils pas en mode console Linux?

J'ai écrit du code QB64 pour essayer les fonctions BASIC INPUT $ et INKEY $ .

Ce programme fonctionne bien lorsqu'il ne fonctionne pas en mode console Linux, mais si nous configurons le logiciel pour qu'il s'exécute en mode console Linux, ce logiciel ne fonctionne pas correctement. Il se bloque.

Je pense que le problème est dû au comportement de la console Linux. Avez-vous une solution de contournement?

Voici le code simple:

$CONSOLE:ONLY
_DEST _CONSOLE

PRINT "Hit a key"
A$ = INPUT$(1)
PRINT A$
PRINT "Hit a key"

B$ = ""
WHILE B$ = "": B$ = INKEY$: WEND
PRINT B$

PRINT "Hit a key"

C$ = INPUT$(1)

PRINT C$


10 commentaires

Vous feriez mieux de poser cette question sur le forum d'assistance QB64 plus ou moins officiel .


Oui je suis d'accord. D'après ce que je sais, les deux personnes sur SO qui surveillent les questions QB ici ne prennent pas en charge QB64 mais plutôt les versions officielles de Microsoft QB telles que 4.5.


Imaginez que INKEY $ renvoie CHR $ (0) + "K" pour la touche curseur gauche et CHR $ (0) + "OK" pour la touche Keypad-Left sur le pavé numérique (aka "numpad"). Imaginez maintenant qu'il n'a fait cela que dans la version Windows; Les machines Mac et Linux renverraient chacune des choses différentes, selon que vous utilisez iTerm2, Terminal.app, xterm, rxvt-unicode, la console Linux, tmux ... Maintenant vous avez une idée de pourquoi les fonctions ne le sont probablement pas mis en œuvre. Les bibliothèques comme terminfo sont quelque peu utiles, mais ils ne sont toujours pas idéaux .


Comme expliqué dans ce lien, il existe des séquences de contrôle et de décalage DEC qui gâchent les choses. Par exemple, vous pouvez faire printf '\ 033 ='; chat; printf '\ 033>' pour activer le "mode clavier numérique", attendez une entrée autre que Ctrl-D (essayez de taper des choses et quittez avec Ctrl-D), et enfin réactivez le "mode clavier d'application". Si vous avez un vrai pavé numérique (pas un de ces ordinateurs portables idiots qui n'ont pas de touches de curseur et nécessitent Fn- ), vous remarquerez que les touches de curseur de la section d'édition du clavier donnent des séquences d'octets différentes de celles du clavier. touches de curseur sur le pavé numérique, en supposant que le verrouillage numérique est désactivé


J'ai essayé de régler le terminal avec -icanon ou raw. stty -icano , stty raw , mais le programme ne s'exécute pas car n'accepte aucune entrée, les caractères standard sont également refusés.


@SirJoBlack C'est parce que INKEY $ n'est pas implémenté dans la console pour Linux (ou dans xterm ou tout autre terminal, émulateur de terminal, etc.): QB64 ne lit même pas les séquences de caractères du TTY lors de l'utilisation INKEY $ et INPUT $ .


Il existe des fonctions supplémentaires du clavier QB64 _KEYCLEAR, _KEYHIT, _KEYDOWN que vous pouvez consulter.


@ChronoKitsune, je comprends que chaque système a un jeu différent pour les touches spéciales (c'est-à-dire: touche de curseur, touche de fonction, etc.). Mais si nous savons ce fait, cela ne devient pas un problème. Pourquoi ne devrait-il pas être autorisé à utiliser inkey $ pour intercepter les codes ASCII standard? Je pense que le manque d'implémentation de INKEY $ est dû à d'autres faits.


@SirJoBlack Il se peut que trop peu de gens sachent comment gérer les détails de niveau inférieur des terminaux. Voici une version fonctionnant pour ASCII et rien d'autre; il lit exactement 1 octet et supprime les octets au-delà de 127 (DEL) . Vous pouvez l'utiliser via DECLARE LIBRARY (voir le commentaire en haut), mais cela prend un peu plus que d'appeler INKEY $ ou _KEYHIT . Ne soyez pas intimidé par le long commentaire en haut. Vous n'avez pas à vous en soucier si vous ne traitez qu'avec ASCII sur une machine locale. J'espère que ça marche pour toi!


Le Wiki QB64 dit le texte suivant: _DEST _CONSOLE peut définir la destination pour envoyer des informations à une fenêtre de console en utilisant PRINT ou INPUT.


3 Réponses :


1
votes

Cette fonction keyhit peut effectivement fonctionner sous Linux:

PRINT "Hit <escape>:"
DO
    _LIMIT 20
    x = _KEYHIT
    IF x = 27 THEN EXIT DO
LOOP
PRINT "Escape pressed."

Ou tester une clé:

PRINT "Hit a key:"
DO UNTIL _KEYHIT
    _LIMIT 20
LOOP
PRINT "Key pressed."


3 commentaires

Salut, j'ai essayé de suivre votre suggestion. Il fonctionne correctement dans le bureau Linux même en tant que input $ et inkey $ , mais les fonctions que vous m'avez indiquées ne s'exécutent pas sous la console, même en définissant la console comme raw (stty raw) ou non canonique (stty -icanon). C'est le même comportement de input $ et inkey $ .


J'ai besoin d'un programme qui s'exécute en mode console, un programme qui commence par les lignes suivantes: $ CONSOLE: ONLY , _DEST _CONSOLE . Ces deux lignes sont capables d'expliquer au compilateur qu'il a besoin de produire un programme qui ne fonctionne pas en OPEN-GL, mais en mode texte uniquement.


À moins que vous ne trouviez un moyen d'ouvrir la console pour les E / S, je ne vois aucun moyen de le faire.



0
votes

Je viens d'exécuter ce code: il refuse de piéger toute activité du clavier dans Win10 sous Linux.

Peut-être que le mode console est pour la sortie uniquement !?

$CONSOLE
_DEST _CONSOLE
$SCREENHIDE
FOR L = 1 TO 10
   PRINT L;
NEXT
DO
    x = _KEYHIT
    IF x THEN END
LOOP
END


2 commentaires

Le moyen d'obtenir des informations de la console existe, vous pouvez utiliser la commande INPUT qui s'exécute également dans la console texte. Mais cette commande ne vous permet pas d'appuyer sur une touche et d'obtenir un résultat sans appuyer sur Entrée.


@SirJoBlack C'est parce que INPUT et LINE INPUT reçoivent du texte de l'entrée standard, qui le reçoit du terminal (sauf si l'entrée standard est redirigée). Malheureusement, l'entrée standard et le terminal lui-même sont mis en mémoire tampon d'une certaine manière comme je l'explique dans cette réponse . Vous pouvez désactiver le mode canonique pour désactiver le comportement EOF (Ctrl-D) et l'exigence EOL pour le terminal, et vous pouvez travailler directement avec le terminal de contrôle (toujours / dev / tty sous Linux avec glibc AFAIK) pour contourner l'ensemble des problèmes de redirection et de mise en mémoire tampon stdin .



1
votes

Le moyen d'obtenir des informations depuis la console existe. Nous pouvons utiliser la commande INPUT , mais cela ne nous permet pas d'éviter d'appuyer sur la touche pour saisir les données. Ma question portait sur l'utilisation de INKEY $ et INPUT $ qui nous permettraient de ne pas appuyer sur la touche .

Le code suivant fonctionne correctement sous Linux console, mais n’est pas la solution à cette question.

$CONSOLE:ONLY
_DEST _CONSOLE

INPUT A
PRINT A


0 commentaires