Autor Thema: getc , Tastaturtreiber  (Gelesen 10003 mal)

NANOcoder

  • Beiträge: 10
    • Profil anzeigen
Gespeichert
« am: 12. February 2011, 23:53 »
Guden allezusammen  ^^

Ich bin recht neu hier und ist mein erster Beitrag.

Wie das Theme schon heist getc und Tastaturtreiber.
Ich steh grad vor dem Problem eine funktion zu schreiben um Buchstaben oder überhaupt erst mal zeichen einzulesen nach einem ENTER tastendruck. Ich hab zwar ähnliche dinge in sufu gesehen aber nichts richtiges gefunden und wenn doch tut mir leid das ich nicht gefunden haben ;)

Also ich kann zwar zeichen einlesen und diese dann in der main vergleichen aber wie kann ich eine "scanf()" ähnliche funktion schrieben die erst nach einem ENTER druck auch einliest ? Da wenn ich eine einfache if vergleich mache dann liest er sofort den buchstabe bei Tastendruck.

Theoretisch dachte ich das ich da was bei den Interrupts machen muss aber ich weiß nicht wie genau das gehen soll auch habe ich mehrere tuts durch gelesen wo zwar der code steht aber nicht wie das genau funktioniert, denn ich will ja keine codes schnurren oder einfach nur kopieren  :-D

Ich hoffe ihr konntet verstehen was ich meine und wollte noch mal sagen das ich jetzt keinen Code-Schnipsel von jeden möchte um den einfahc nur copy-paste mache . Theoretische Iden reichen mir erst mal aus

danke schon mal für ein paar theoretische Anregungen ^^


PNoob

  • Beiträge: 106
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #1 am: 13. February 2011, 00:56 »
wenn ich dich richtig verstehe pollst du momentan und willst das ganze jetzt insterrupt gesteuert machen?

PNoob

NANOcoder

  • Beiträge: 10
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 13. February 2011, 01:12 »
naja was heist will ^^ also ich will ne getc funktion  es gibt zwar mehrere die schon erklärt sind auch hier im forum aber wie bekomme ich das hin das er die zeichen bzw. später dann strings erst nach ENTER "liest" da ich momentan eine globale variabel habe die gespeichert wird und in in die getc funktion übergeben wird. Später will ich dann befehle eingeben können um systembefehle wie "reboot" . Nun weiß ich nicht wie ich das mit dem ENTEr tastendruck regeln soll .

Sagen wir nen einfaches beispiel ich hab ne einfache if schleife und wenn ich 0 drücke dann soll der pc herunterfahren bei mir ist das momentan so, sobald ich die 0 drücke rebootet das system automatisch aber nicht nach einem ENTER wie man es von alten C Konsolenprogs gewohnt ist xD

freecrac

  • Beiträge: 86
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 13. February 2011, 09:58 »
Soll es für DOS sein?:

Ralf Browns Interrupt List(RBIL):
http://www.pobox.com/~ralf
http://www.pobox.com/~ralf/files.html
ftp://ftp.cs.cmu.edu/afs/cs.cmu.edu/user/ralf/pub/

RBIL->inter61b.zip->INTERRUP.F
--------D-210A-------------------------------
INT 21 - DOS 1+ - BUFFERED INPUT
   AH = 0Ah
   DS:DX -> buffer (see #01344)
Return: buffer filled with user input
Notes:   ^C/^Break are checked, and INT 23 is called if either detected
   reads from standard input, which may be redirected under DOS 2+
   if the maximum buffer size (see #01344) is set to 00h, this call returns
     immediately without reading any input
SeeAlso: AH=0Ch,INT 2F/AX=4810h

Format of DOS input buffer:
Offset   Size   Description   (Table 01344)
 00h   BYTE   maximum characters buffer can hold
 01h   BYTE   (call) number of chars from last input which may be recalled
      (ret) number of characters actually read, excluding CR
 02h  N BYTEs   actual characters read, including the final carriage return

Dirk

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 13. February 2011, 10:29 »
Hm, wen interessiert heutzutage noch DOS? ;)

Du willst ein char-Array nehmen und dort hintereinander Zeichen einlesen. Wenn Enter gedrückt wird, schreibst du ein Nullbyte ans Ende der eingelesenen Zeichen und fertig ist dein String. Zum Vergleichen musst dir dann ein strcmp() schreiben.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 13. February 2011, 10:33 »
Hallo,


für ein scanf benötigt man einen internen Puffer in den erst mal alle Zeichen (die der User so eintippt) rein kommen und das ganze erst dann weitergeleitet wird wenn das ENTER kommt.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

NANOcoder

  • Beiträge: 10
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 13. February 2011, 10:50 »
hey danke für die schnellen antworten ^^

das heist ich mach ne vari char als array und als ENTER muss ich ein NUllbyte am ende des strings rein schreiben.

@erik.vikinger
also eine globale  variabel steht schon da ich ja schon einzelne zeichen einlesen kann nur mit mit ENTER prob muss ich noch mal ausprobieren ^^

@all
danke schon mal ich werd mich schonmal damit auseinder setzten und mal nen wenig coden  :-D

NANOcoder

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 13. February 2011, 14:39 »
Du liest so lange in einen Puffer ein, bis du ein Enter findest, erst danach analysierst du, was du eigentlich gefunden hast. Das kann dann z.B. so aussehen:

char buf[25], tmp; int index=0;
while( index < 25 ) { /* Pufferüberlauf verhindern */
    tmp = lies_ein_zeichen();
    if ( (tmp != 13) && (tmp != 10) ) { /* kein ENTER (CR/LF) gedrückt */
        buf[index] = tmp;
        index = index + 1;
    } else {
        break; /* das war jetzt ein ENTER, mach weiter */
    }
}
if ( (buf[0] == 'b') && (buf[1] == 'o') && (buf[2] == 'o') && (buf[3] == 't') ) {
    /* er hat 'boot' eingegeben */
    reboote_das_system();
}

Den Vergleich unten solltest du durch strncmp ersetzen, wenn du eine passende Funktion hast. Für eine richtige Shell gehört noch ein bisschen mehr dazu, aber das ist ein Ansatz.

Viel Erfolg!

NANOcoder

  • Beiträge: 10
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 13. February 2011, 19:49 »
hey danke für die infos muss nur noch zeit finden das alles zu machen hab auch schon ne idee wie ich es ungefähr mache ;)


erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 14. February 2011, 11:05 »
Hallo,


auch die Backspace-Taste und die Entfernen-Taste (und natürlich die Kursor-Tasten für Links und Rechts) sollten beim Zusammenbauen des Strings korrekt benutzt werden können (sonnst könnten die User der Shell niemals einen Tippfehler korrigieren).


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

NANOcoder

  • Beiträge: 10
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 14. February 2011, 12:19 »
theoretisch müsste ich ja den bei einer entfern-Taste oder backspace ein zeichen aus dem string herauslöschen udn diesen dann wieder neu rein schreiben in den string.

NANOcoder

PNoob

  • Beiträge: 106
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #11 am: 14. February 2011, 18:56 »
jo genau. bei der entf Taste den der nach dem aktuellem Curser ist und bei der Backspace Taste den hinter dem Curser. ein druck auf die entf Taste muss wenn der Curser am ende des eingegebenen steht ohne effekt bleiben.

PNoob

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 14. February 2011, 20:15 »
Hallo,


wenn die Backspace-Taste oder die Entfernen-Taste mitten im Text gedrückt wird muss der hintere Teil des Strings natürlich um ein Byte nach vorne kopiert werden (es dürfen keine Lücken entstehen).
Wenn die Backspace-Taste am Stringanfang gedrückt wird dann muss diese auch ohne Effekt bleiben.

Das ist aber alles nicht so schwer, das läuft nur auf ne kleine Hand voll Regeln hinaus die das Verhalten exakt vollständig beschreiben.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

freecrac

  • Beiträge: 86
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 15. February 2011, 10:29 »
Hm, wen interessiert heutzutage noch DOS? ;)
Na alle Programmierer die vom Retro-Feeling der alter DOS-Kisten begeistert sind!

Dirk

NANOcoder

  • Beiträge: 10
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 28. February 2011, 20:06 »
Hallo mal wieder ^^,

Ich hab mal in meiner main.c den code von svenska laufen lassen als Test um zu schauen ob es überhaupt funtz mit meiner strcmp funktion jedoch passiert da rein gar nichts :(
Hier meine strcmp funktion:

...

int strcmp(char* string1, char* string2)
{
      int i = 0;
      int fail = 0;
      while(string1[i] != '\0' && string2[i] != '\0')
      {
          if(string1[i] != string2[i])
          {
              fail = 1;
              break;
          }
          i++;
      }
     
      if( (string1[i] == '\0' && string2[i] != '\0') || (string1[i] != '\0' && string2[i] == '\0') )
          fail = 1;
 
      return fail;
}

...


dann in der main.c :

...

char buf[25], tmp; int index=0;
char reb[] = {'r','e','s','t','a','r','t'};

for(;;)
{

while( index < 25 )
{
    tmp = getc();

    if ( (tmp != 13) && (tmp != 10) )
    {
        buf[index] = tmp;
        index++;
    }
    else
     {
        break;
     }

}

    if ( strcmp(buf,reb) == 0 )
    {
   
    restart();
    }

   //if(...)
   //{
   //...
   //}

}

...

Wie gesagt um zu sehen ob es überhaupt funktioniert hab ich das mal das so improvisiert.

Wenn ich jetzt das laufen lasse mittels VirtualBox kann ich zwar wie gewohnt meine schönen Buchstaben am Bildschirm tippen jedoch passiert nicht wenn ich z.B restart eingebe , muss ich da villt so was wie nen "volatile" deklarieren ?

Oder es liegt an meiner strcmp-funktion, wobei ich die tausend mal durch gechekt habe.
Wenn das dann funtz will ich es so umschreiben das wenn man nen fehler macht das noch verbessern kann und schließlich dann ENTER-drückt um die strings dann zu vergleichen.

NANOcoder
« Letzte Änderung: 28. February 2011, 20:09 von NANOcoder »

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 28. February 2011, 20:20 »
Hallo,


char reb[] = {'r','e','s','t','a','r','t'};
Kann sein das mein C etwas eingerostet ist aber ich denke dieser String ist nicht 0-terminiert.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

NANOcoder

  • Beiträge: 10
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 28. February 2011, 20:36 »
upps ^^ naja ich habs auch mit 0-terminiert und funtz auch net das war halt so als ich das wieder umgeändert hatte aus irgendein grund ^^

Und die restart()-funktion funktioniert einwandfrei wenn ich sie mit ner ganz einfachen if-schleife vergleiche mit ner nummer wie z.b. 1 oder 'a'
 prob is jetzt nur strings und nach einem ENTER ^^ Ich bin noch mal selbst am nachschauen wo der fehler liegt aber bis jetzt habe ich keine idee. Hoffentlich ist das nicht so nen hässlicher kleiner fehler ;)
 
Grüße
NANOcoder
« Letzte Änderung: 28. February 2011, 20:42 von NANOcoder »

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 01. March 2011, 02:37 »
Funktioniert dein getc()?
Was gibt dir getc() für Werte zurück, wenn du Tasten drückst? Welchen Wert hat ENTER?

Ich bin im Beispielcode von ASCII-Werten ausgegangen, nicht von Tastatur-Scancodes.

Die Eingabe wird übrigens nicht nullterminiert, da müsstest du hinter das "else" noch ein >>buf[index]='\0';<< setzen, und du solltest den Teststring ebenfalls nullterminieren.

Das strcmp() sieht spontan erstmal gut aus.

Gruß,
Svenska

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 01. March 2011, 09:24 »
char reb[] = {'r','e','s','t','a','r','t'};Das kann man übrigens auch so schreiben und hat damit die Nullterminierung auch erledigt:
char reb[] = "restart";
Was die Nullterminierung angeht, fehlt sie natürlich nicht nur im else-Zweig, sondern auch, wenn mehr als 25 Zeichen eingegeben wurden. Ich würde die Schleife also nur bis 24 laufen lassen und dahinter ein buf[index] = '\0'; einbauen.

Und strcmp sieht zwar für deinen Zweck hier ausreichend aus, ist aber natürlich kein echtes strcmp (man kann nicht unterscheiden, welcher String "größer" ist).
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

NANOcoder

  • Beiträge: 10
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 01. March 2011, 21:04 »
Also die getc()-funktion geht hab ich schon mehrmals ausprobiert, die funktion sollte funzen da ich ,wie gesagt, sie schon mit einzelnen zeichen 1 oder a probiert habe und dann noch eine restart funktion gemacht habe , hat super geklappt also daran sollte es nicht liegen.

Also die strcmp war mir auch erst spontan eingefallen und hab mir auch überlegt das sie ja "erst" mal ausreichen sollte. Bei mir dauert das immer ein wenig bis sich da was verändert und fällt mir immer spontan ein das umgeändert werden muss :-D

Ich werde das ganze noch mal ausprobieren und austesten ich werde mich dann melden.


Danke noch mal für die schnellen Antworten  :wink:

 

Einloggen