J'essaie de récupérer les coordonnées du curseur dans une borne VT100 à l'aide du code suivant: J'utilise la séquence d'échappement ANSI suivante: P> rapport d'état du périphérique - ESC [6N P>
rapporte la position du curseur à la
application comme (comme si elle est saisie au clavier) ESC [N; MR, où n est
la ligne et m est la colonne. P>
blockQquote> Le code compile et la séquence ANSI est envoyée, mais, lors de la réception, le terminal imprime le Clairement, la chaîne est désignée pour le programme, cependant, je dois donc faire quelque chose de mal à tort. Est-ce que quelqu'un sait ce qu'il est? P> p>
^ [[[x; yr code> chaîne sur
stdout code > Au lieu de
stdin code>, ce qui le rend impossible pour moi de le récupérer à partir du programme: p>
P>
4 Réponses :
Votre programme fonctionne mais attend un personnage EOL. P>
La solution consiste à utiliser quelque chose d'autre qui n'a pas besoin d'une nouvelle ligne pour lire l'entrée, puis utilisez SSCANF pour analyser les valeurs. P>
Vous aurez également besoin de rendre STDIN non bloquant ou vous n'obtiendrez pas l'entrée tant que le tampon est plein ou que STDIN est fermé. Voir cette question Faire blocage de stdin p>
Vous devez également appeler scanf code> est orienté ligne afin qu'il attend une nouvelle ligne avant le traitement. Essayez d'exécuter votre programme puis appuyez sur la touche Entrée. P>
fflush (stdout); code> après que votre Printf pour vous assurer qu'il est réellement écrit (PrintF est souvent la ligne tamponnée, donc sans nouvelle ligne, il peut ne pas rincer le tampon). P>
N'y a-t-il pas une façon de rendre la commande ANSI ne pas écrire ^ [[x; yr code> à la borne du tout? Je voudrais extraire silencieusement les coordonnées sans aucun changement visible sur l'écran du terminal. Mais cela écrit sur le terminal (indésirable lors de la création d'une interface graphique textuelle) et modifie ainsi les coordonnées du curseur (ce qui le rend absolument inutile).
C'est pourquoi les malédictions (et les ncurses) existent pour que vous n'ayez pas à vous soucier de tous ces détails.
Bien sûr, mais les ncurses sont un bloatware. C'est pourquoi j'écris mes propres séquences d'échappement ANSI léger ANSI LIB, qui soutient simplement VT100. Mais oui, on dirait que je vais juste avoir à DL NCurses et essayer d'inverser l'ingénieur pour trouver sa solution à ce problème.
Je pense que les ncurses ne tiennent pas une trace de l'endroit où le curseur est en interne ou le déplace vers un emplacement connu avant la sortie. Il faut parce que certains terminaux ne peuvent pas signaler le lieu actuel.
Je demande la position du curseur. Si je n'ai pas de réponse après 100 ms (ceci est arbitraire), je suppose que la console n'est pas une ANSI.
Je crois que vous obtenez vraiment la réponse attendue à Stdin. Mais imaginez ce qui se passe réellement: p>
Pour éviter cela, utilisez un Mais avant de rencontrer la boucle, vous devez Modifier avec TERMIOS en mode RAW (regardez l'exemple de code ci-dessous) . Sinon rien ne serait différent. P> getc () code> (
== fget (stdin) code>) boucle à la place. Si vous rencontrez un ESC (
0x1b code>) que de vider les caractères suivants d'une chaîne jusqu'à ce que vous trouviez le délimiteur final de la séquence ESC (dans votre cas
'n' code>). Après cela, vous pouvez utiliser
sscanf (esqstring, formaformer, ...) code>. P>
#include <stdlib.h> #include <stdio.h> #include <conio.h> void readCoord(void* row, void* col){ int i = 0; char* input = malloc(10); printf("\e[6n"); while(!_kbhit()) _sleep(1); while(_kbhit()) *(input + (i++)) = getch(); *(input + i) = '\0'; sscanf(input, "\e[%d;%dR", row, col); } void main(void){ int i = 0, r, c; char* coord = malloc(10); printf("Hello"); readCoord(&r , &c); printf("\nYour coordinate is (%d, %d)", c, r); } _kbhit() is used to detect input (DSR are treated as though typed at the keyboard), and getch() to read and remove the character from standard inputThis program relies on conio.h, which is not a standard and hence not recommended for portable C programs.