Textinmatning i C
Textinmatning i C
Jag håller på att skriva ett litet spel i C. Det ska bli snake och är en inlämningsuppgift. Själva spelet är nästan klart förutom själva textinmatningen, just nu måste man trycka bokstav + enter för att ormen ska flytta på sig, inte helt lyckat. Så jag skulle behöva en funktion som kan läsa ett tecken från terminalen utan att vänta på \n.
Vi har fått en fil med några funktioner färdigskrivna som ska göra detta, problemet är att den filen kräver termios.h som inte verkar ingå i MinGW som föreläsaren rekommenderar om man kör Windows.
Vi har fått en fil med några funktioner färdigskrivna som ska göra detta, problemet är att den filen kräver termios.h som inte verkar ingå i MinGW som föreläsaren rekommenderar om man kör Windows.
Funderat lite till...
Programmet ska ju fungera så här:
Flytta en position i nuvarande riktning
Om någon tangent har blivit nertryckt ska riktningen ändras
Göra en "lagom" lång paus
Börja om
Det är precis så det kodskelettet vi har fått fungerar, fast det skelettet använder funktioner ur termios.h.
Jag har tittat i min bok och sökt på internet men inte hittat något bra, svårt att hitta något när man inte vet vad det man leter efter heter.
Men lösningen kanske är att sätta sig vid en långsam linuxdator med flimrande skärm i några timmar.
Programmet ska ju fungera så här:
Flytta en position i nuvarande riktning
Om någon tangent har blivit nertryckt ska riktningen ändras
Göra en "lagom" lång paus
Börja om
Det är precis så det kodskelettet vi har fått fungerar, fast det skelettet använder funktioner ur termios.h.
Jag har tittat i min bok och sökt på internet men inte hittat något bra, svårt att hitta något när man inte vet vad det man leter efter heter.
Men lösningen kanske är att sätta sig vid en långsam linuxdator med flimrande skärm i några timmar.
- MadModder
- Co Admin
- Inlägg: 31166
- Blev medlem: 6 september 2003, 13:32:07
- Ort: MadLand (Enköping)
- Kontakt:
Hittade nånting
"This has nothing to do with gcc or any other compiler but with the terminal/
All the input is buffered and send to a program only when enter is pressed no matter if you are reading the input in your program character by character or not. To get an unbuffered input which means get a character just after the key is pressed you need to mess with the terminal or use ncurses."
Ingenting som har med ditt problem att göra?
"This has nothing to do with gcc or any other compiler but with the terminal/
All the input is buffered and send to a program only when enter is pressed no matter if you are reading the input in your program character by character or not. To get an unbuffered input which means get a character just after the key is pressed you need to mess with the terminal or use ncurses."
Ingenting som har med ditt problem att göra?
MadModder: Det är nog det föreläsaren försökte säga när han jag frågade om hur koden i skelettet fungerar, fast han sa mest "inget som ni behöver förstå". Men han nämde att koden ändrade någonting med bufferten och det kanske är så att hans lösning bara fungerar i linux. Men jag ska titta lite hur ncurses fungerar.
Ett annat problem med inlämningsuppgiften är att den ska göras två och två, något som jag inte tycker om när det är så är små program. Det blir lätt så att man experimenterar lite själv och helt plötsligt är programmet nästan färdigt.
Ett annat problem med inlämningsuppgiften är att den ska göras två och två, något som jag inte tycker om när det är så är små program. Det blir lätt så att man experimenterar lite själv och helt plötsligt är programmet nästan färdigt.
Jag gjorde samma sak i MS QuickC en gång, då använde jag getch() och getche() för att få enstaka tecken-inmatningar.
Den senare ekar det inmatade tecknet på skärmen.
Jag har faktiskt kvar MS QuickC V2.5 av någon pervers anledning...
Här är exempel-programmet för getch() och getche():
De är inte så bra för inläsning av tryck på t ex piltangenter, eller annat som inte har ASCII-tecken, för då måste man trycka två gånger för att scankoden ska läsas in.
Det finns ett annat exempel-program som läser på scankoderna direkt, och den fick jag faktiskt användning av på ett tidigt jobb, där jag i ett skede skulle testa egentillverkade tangentbord till industriterminaler:Allt det här körs på Microsofts runtime-bibliotek för DOS, kanske inte användbart rakt av för dig. 
Den senare ekar det inmatade tecknet på skärmen.
Jag har faktiskt kvar MS QuickC V2.5 av någon pervers anledning...
Här är exempel-programmet för getch() och getche():
Kod: Markera allt
/* GETCH.C illustrates how to process ASCII or extended keys.
* Functions illustrated include:
* getch getche
*/
#include <conio.h>
#include <ctype.h>
#include <stdio.h>
void main()
{
int key;
/* Read and display keys until ESC is pressed. */
while( 1 )
{
/* If first key is 0, then get second extended. */
key = getch();
if( (key == 0) || (key == 0xe0) )
{
key = getch();
printf( "ASCII: no\tChar: NA\t" );
}
/* Otherwise, there's only one key. */
else
printf( "ASCII: yes\tChar: %c \t", isgraph( key ) ? key : ' ' );
printf( "Decimal: %d\tHex: %X\n", key, key );
/* Echo character response to prompt. */
if( key == 27)
{
printf( "Do you really want to quit? (Y/n) " );
key = getche();
printf( "\n" );
if( (toupper( key ) == 'Y') || (key == 13) )
break;
}
}
}
Det finns ett annat exempel-program som läser på scankoderna direkt, och den fick jag faktiskt användning av på ett tidigt jobb, där jag i ett skede skulle testa egentillverkade tangentbord till industriterminaler:
Kod: Markera allt
/* KEYBRD.C illustrates:
* _bios_keybrd
*/
#include <bios.h>
#include <stdio.h>
#include <ctype.h>
/* Macro to peek at a specified memory address */
#define peek( addr ) (*(unsigned char _far *)addr)
void main()
{
unsigned key, shift, scan, ascii = 0;
int kread = _KEYBRD_READ;
int kready = _KEYBRD_READY;
int kshiftstatus = _KEYBRD_SHIFTSTATUS;
/* If bit 4 of the byte at 0x0040:0x0096 is set, the new keyboard
* is present.
*/
if( peek( 0x00400096 ) & 0x10 )
{
kread = _NKEYBRD_READ;
kready = _NKEYBRD_READY;
kshiftstatus = _NKEYBRD_SHIFTSTATUS;
}
printf( "New keyboard %s\n",
(kread == _NKEYBRD_READ) ? "present" : "not present" );
/* Read and display keys until ESC is pressed. */
while( ascii != 27 )
{
/* Drain any keys in the keyboard type-ahead buffer, then get
* the current key. If you want the last key typed rather than
* the key currently being typed, omit the initial loop.
*/
while( _bios_keybrd( kready ) )
_bios_keybrd( kread );
key = _bios_keybrd( kread );
/* Get shift state. */
shift = _bios_keybrd( kshiftstatus );
/* Split key into scan and ascii parts. */
scan = key >> 8;
ascii = key & 0x00ff;
/* Categorize key. */
if( (ascii == 0) || (ascii == 0xE0 ) )
printf( "ASCII: no\tChar: NA\t" );
else if( ascii < 32 )
printf( "ASCII: yes\tChar: ^%c\t", ascii + '@' );
else
printf( "ASCII: yes\tChar: %c \t", ascii );
printf( "Code: %.2X\tScan: %.2X\t Shift: %.4X\n",
ascii, scan, shift );
}
}
