Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Nullchecker
Anmeldungsdatum: 03.08.2013 Beiträge: 34
|
Verfasst am: 20.06.2014, 12:49 Titel: Zählschleife funktioniert nicht 100%ig |
|
|
Bei meinem Programm ist mir ein kleines Problem aufgefallen. Und zwar gebe ich auf dem Bildschirm die Nummer des aktuellen Datensatzes aus. Mit den Pfeiltasten kann man vor- bzw. zurückblättern. Klappt soweit, bis auf folgendes: Z.B. gehe ich bis vor auf Datensatz Nr. 20, lese ihn durch, will dann auf Nr. 19 zurück, er springt aber erst auf 21. Umgekehrt dasselbe, also statt auf 21 springt er auf 19. Danach zählt er aber wieder richtig. Woran liegt es?
Hier meine Zählschleife:
Code: | gt= INKEY
DO : LOOP WHILE LEN(INKEY)
SLEEP
IF gt= CHR(255, 72) then x= x+1 : IF x=251 then x=x-1
IF gt= CHR(255, 80) then x= x-1 : IF x=-1 then x=x+1
IF gt= CHR(255, 59) then EXIT DO |
|
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 20.06.2014, 15:27 Titel: 2 DO-Schleifen verschachteln |
|
|
Hallo,
INKEY wartet nicht auf einen Tastendruck, sondern prüft nur im Augenblick seiner Ausführung, ob es einen zu verarbeiten gibt. Ist dies zum Ausführungszeitpunkt von INKEY nicht der Fall, d. h. es liegt kein Tastendruck zur Verarbeitung an, wird sofort der Leerstring "" zurückgegeben.
Daher muss man die Überprüfung, ob eine Taste gedrückt wurde - und wenn ja, welche - ständig ausführen. Es reicht nicht, ein einziges Mal zu Beginn den Tastendruck zu prüfen und anschließend einfach zu warten, bis irgendetwas im Tastaturpuffer liegt. In deinem jetzigen Code-Schnipsel müsstest du praktisch im ersten Bruchteil einer Sekunde die richtige Taste drücken, also noch bevor der Code in die DO-Schleife eintritt. (Bemerkung am Rande: Eine DO-Schleife ist keine Zählschleife.)
Hier mal ein funktionierendes Beispiel:
Code: | Const MaxDatensatzNr = 10 'Anpassbar
Dim DatensatzNr As Integer = 0
Dim Tastendruck As String
Print "Druecken Sie die linke oder die rechte Pfeiltaste, um zu navigieren."
Print "Durch [ESC] verlassen Sie die Verarbeitungsschleife."
Print
'Hauptschleife:
Do
'Aktuellen Datensatz anzeigen:
Print "Aktueller Datensatz: " & DatensatzNr
'Unterschleife:
'Warten, bis der Benutzer eine Taste drueckt:
Do
Tastendruck = INKEY
Sleep 10
Loop Until Len(Tastendruck)
'Wenn wir hier ankommen, hat der Benutzer irgendeine Taste gedrueckt.
Select Case Tastendruck
Case Chr(255, 75): 'Pfeiltaste links
If (DatensatzNr > 0) Then
DatensatzNr -= 1
Else
Beep 'Weiter zurueck geht's nicht. Fehlerpieps
End If
Case Chr(255, 77): 'Pfeiltaste rechts
If (DatensatzNr < MaxDatensatzNr) Then
DatensatzNr += 1
Else
Beep
End If
Case Else:
'Wenn es weder PfeilLinks noch PfeilRechts war, waere nur noch
'ESC (Schleifenabbruch-Bedingung) erlaubt. Alles andere soll nur
'den Fehler-Piepton erzeugen.
If (Tastendruck <> CHR(27)) Then Beep
End Select
Loop Until Tastendruck = Chr(27)
Print
Print "Sie haben die Schleife ESC verlassen. Druecken Sie nun irgendeine Taste,"
Print "um das Programm zu beenden."
GetKey
End |
Viele Grüße!
Sebastian _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
 |
Nullchecker
Anmeldungsdatum: 03.08.2013 Beiträge: 34
|
Verfasst am: 20.06.2014, 18:07 Titel: |
|
|
Habe mir Deine Erklärung mal durch den Kopf gehen lassen. Darauf hin bin ich zu folgendem Ergebnis gekommen:
DO : LOOP WHILE LEN(INKEY)
SLEEP
gt= INKEY
IF gt= CHR(255, 72) then x= x+1 : IF x=251 then x=x-1
IF gt= CHR(255, 80) then x= x-1 : IF x=-1 then x=x+1
IF gt= CHR(255, 59) then EXIT DO
Du siehst, ich habe lediglich die Reihenfolge geändert und es funktioniert.
Deine Erklärungen sind wirklich gut,so dass man in der Lage ist selbst zu einer Lösung zu kommen. Wie gehabt Danke ich für die schnelle Antwort, da es mich ja weiterbringt ohne lange warten zu müssen. Darüber hinaus hoffe ich euch mit meinen "Problemchen" nicht zu Nerven. Ich bin eben nur ein Hobbyprogrammierer. |
|
Nach oben |
|
 |
Nullchecker
Anmeldungsdatum: 03.08.2013 Beiträge: 34
|
Verfasst am: 21.06.2014, 09:32 Titel: |
|
|
Nachtrag:
Nach dem ich nun auch mit Deinem Code gearbeitet habe, bitte ich alle meine "Lösung" zu vergessen.
Es gibt 2 Möglichkeiten:
1stens Sebastians Lösung
2tens Sebastians Lösung
Ich habe mich für Sebastians Lösung entschieden!
@Sebastian : Vielen Dank für Deinen Code (Ich bin einfach zu blöd) |
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
|
Nach oben |
|
 |
C64-Fan
Anmeldungsdatum: 26.10.2012 Beiträge: 79
|
Verfasst am: 07.07.2014, 14:45 Titel: |
|
|
hab da auch ne Tastaturabfrage-Frage,
wenn ich die im endlosschleifen-modus laufen lasse ist das ok? oder doch in besser mit sleep anzuhalten?
wird im ersten Beispiel der Prozessor arbeitsmäßig besser geschont ?
Dim x as string
DO : LOOP WHILE LEN(INKEY)
Do
SLEEP 'soll man das mit sleep schreiben oder kann das weg
x= INKEY
IF x= "j" then x=1 : Exit Do
IF x= "n" then x= 2 : Exit Do
Loop
so gehts zwar auch:
aber isses oben besser?
Do
x= INKEY
IF x= "j" then x=1 : Exit Do
IF x= "n" then x= 2 : Exit Do
sleep 1
Loop _________________ Mitglied-Nr. 2000  |
|
Nach oben |
|
 |
Elor
Anmeldungsdatum: 12.07.2013 Beiträge: 205 Wohnort: Konstanz
|
Verfasst am: 07.07.2014, 17:56 Titel: |
|
|
Hallo,
du solltest SLEEP schon verwenden wenn in einer Schleife abgefragt wird, damit hast du fast keine Prozessor Auslastung.
Dein Beispiel Funktioniert so aber trotzdem nicht. Du kannst einer String-Variablen nicht so einfach eine Zahl zuortnen. |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 07.07.2014, 18:24 Titel: |
|
|
"SLEEP" wartet auf einen Tastendruck, was in diesem Fall passt, aber oft nicht das ist was man will (denke z. B. an eine Mausabfrage o. ä.). Nimm also besser die Variante "SLEEP 1" - das wartet nur eine Millisekunde (theoretisch; in der Praxis wird es länger sein, weil die Zeitauflösung nicht so hoch ist) und gibt in dieser Zeit die Kontrolle kurz ab, sprich: der Prozessor hat Zeit für andere Dinge und die Auslastung durch dein Programm ist gering. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
C64-Fan
Anmeldungsdatum: 26.10.2012 Beiträge: 79
|
Verfasst am: 08.07.2014, 08:43 Titel: |
|
|
Zitat: | Dein Beispiel Funktioniert so aber trotzdem nicht. Du kannst einer String-Variablen nicht so einfach eine Zahl zuortnen. |
sorry stimmt Elor , das beispiel sollte y=1 bzw y=2 heissen
also wenn ich recht verstehe sind beide ok, das obere mit SLEEP ist 'NUR' bei Tastaturabfragen ok,
das untere mit SLEEP 1 auch für Abfragen Maus etc. ? _________________ Mitglied-Nr. 2000  |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 08.07.2014, 17:52 Titel: |
|
|
Konkret wartet ein "SLEEP" bis zum nächsten Tastendruck (ohne dabei den Tastaturpuffer uz leeren), während "SLEEP x" solange wartet, bis eine Taste gedrückt wurde oder x Millisekunden vergangen sind. Was du einsetzt, hängt davon ab, was du haben willst - soll das Programm gestoppt werden, bis eine Taste gedrückt wurde, nehme ich "SLEEP" (wobei ich noch lieber GETKEY nehme, aber dadurch wird der Tastaturpuffer abgebaut); soll das Programm dagegen nur kurz verzögert werden (ob für eine Animation oder eben auch nur zur Prozessorentlastung), nehme ich die Variante "SLEEP x". _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
|