Textinmatning i C

Elektronik- och mekanikrelaterad mjukvara/litteratur. (T.ex schema-CAD, simulering, böcker, manualer mm. OS-problem hör inte hit!)
vikingen
EF Sponsor
Inlägg: 167
Blev medlem: 5 februari 2004, 15:39:43
Ort: Orust

Textinmatning i C

Inlägg av vikingen »

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.
Användarvisningsbild
Icecap
Inlägg: 26612
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

getchar() kanske?
vikingen
EF Sponsor
Inlägg: 167
Blev medlem: 5 februari 2004, 15:39:43
Ort: Orust

Inlägg av vikingen »

Den läser inte något tecken förrän man har tryckt enter, min tanke är ju att ormen ska byta rikting direkt när man har tryckt en tangent, inte efter att man har tryckt en tangent och sedan tryckt enter.
Användarvisningsbild
MadModder
Co Admin
Inlägg: 31166
Blev medlem: 6 september 2003, 13:32:07
Ort: MadLand (Enköping)
Kontakt:

Inlägg av MadModder »

när vi pysslade med pascal i skolan fanns det nåt som man kunde läsa av scankoderna med. Kommer inte ihåg vad det var för nåt.
Borde finnas i C också?
Har du ingen kommandoreferens? I en sån brukar man kunna leta sig fram till vad man vill åt.
vikingen
EF Sponsor
Inlägg: 167
Blev medlem: 5 februari 2004, 15:39:43
Ort: Orust

Inlägg av vikingen »

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.
Användarvisningsbild
MadModder
Co Admin
Inlägg: 31166
Blev medlem: 6 september 2003, 13:32:07
Ort: MadLand (Enköping)
Kontakt:

Inlägg av MadModder »

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?
Användarvisningsbild
Noxin
Inlägg: 614
Blev medlem: 21 september 2006, 11:59:45
Ort: Stockholm, Årsta + Orrefors

Inlägg av Noxin »

I Turbo Pascal heter koden "readkey"

/Klas
vikingen
EF Sponsor
Inlägg: 167
Blev medlem: 5 februari 2004, 15:39:43
Ort: Orust

Inlägg av vikingen »

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.
Maalobs
Inlägg: 1304
Blev medlem: 3 februari 2005, 14:35:15
Ort: Stockholm

Inlägg av Maalobs »

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():

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;
        }
    }
}
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:

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 );
    }
}
Allt det här körs på Microsofts runtime-bibliotek för DOS, kanske inte användbart rakt av för dig. :twisted:
Användarvisningsbild
baron3d
EF Sponsor
Inlägg: 1352
Blev medlem: 1 oktober 2005, 23:58:43
Ort: Torestorp

Inlägg av baron3d »

Titta i <conio.h>.

Syntax:
#include <conio.h>
int getch(void);

Description:
Gets character from keyboard, does not echo to screen.
getch reads a single character directly from the keyboard, without echoing to the screen.

Return Value:
getch returns the character read from the keyboard.
Skriv svar