Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Zählschleife funktioniert nicht 100%ig

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Nullchecker



Anmeldungsdatum: 03.08.2013
Beiträge: 34

BeitragVerfasst am: 20.06.2014, 12:49    Titel: Zählschleife funktioniert nicht 100%ig Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 20.06.2014, 15:27    Titel: 2 DO-Schleifen verschachteln Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Nullchecker



Anmeldungsdatum: 03.08.2013
Beiträge: 34

BeitragVerfasst am: 20.06.2014, 18:07    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Nullchecker



Anmeldungsdatum: 03.08.2013
Beiträge: 34

BeitragVerfasst am: 21.06.2014, 09:32    Titel: Antworten mit Zitat

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! lächeln

@Sebastian : Vielen Dank für Deinen Code (Ich bin einfach zu blöd)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 21.06.2014, 13:07    Titel: Antworten mit Zitat

Nullchecker hat Folgendes geschrieben:
@Sebastian : Vielen Dank für Deinen Code (Ich bin einfach zu blöd)

Kein Problem, gern geschehen. Und gar nicht blöd. Alle hier haben mal irgendwann angefangen. lächeln
_________________

Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
C64-Fan



Anmeldungsdatum: 26.10.2012
Beiträge: 79

BeitragVerfasst am: 07.07.2014, 14:45    Titel: Antworten mit Zitat

hab da auch ne Tastaturabfrage-Frage, lachen
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 lächeln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Elor



Anmeldungsdatum: 12.07.2013
Beiträge: 205
Wohnort: Konstanz

BeitragVerfasst am: 07.07.2014, 17:56    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4702
Wohnort: ~/

BeitragVerfasst am: 07.07.2014, 18:24    Titel: Antworten mit Zitat

"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
Benutzer-Profile anzeigen Private Nachricht senden
C64-Fan



Anmeldungsdatum: 26.10.2012
Beiträge: 79

BeitragVerfasst am: 08.07.2014, 08:43    Titel: Antworten mit Zitat

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 lächeln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4702
Wohnort: ~/

BeitragVerfasst am: 08.07.2014, 17:52    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz