Schleifenunterbrechung für Eingabeabfrage

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Schleifenunterbrechung für Eingabeabfrage

    Hallo!

    Habe eine kleine App programmiert, bei der die Grundrechnungsarten trainiert werden können. Dabei werden 2 Zufallszahlen generiert. Der User soll anschließend den errechneten Wert in ein Outlet einfügen. Nachdem der die Enter-taste gedrückt hat wird das Ergebnis kontrolliert und eine Meldung ausgegeben. Da man aber gleich mehrere Rechnungen in Auftrag geben kann brauch ich nach der Erstellung der Zufallszahlen eine Pause, in der der User sein Ergebnis eingeben kann und anschließend die Kontrolle auslöst. Habe versucht dies mit einer Warteschleife und einer Variablen zum Ausstieg aus der Schleife probiert, die nach der Kontrolle gesetzt wird. Leider hängt sich dabei das Programm auf. Die Verwendung von wait führt zwar zu einem Erfolg im ersten Durchlauf, dafür schaffe ich aber nicht das wait wieder aufzulösen

    anbei der verwendete Code:
    #import "AppDelegate.h"

    int Addition (int numberOne, int numberTwo)
    {
    int sum = numberOne + numberTwo;
    return sum;
    }

    int Subtraction (int numberOne, int numberTwo)
    {
    int sum = numberOne - numberTwo;
    return sum;
    }

    int Multiplication (int numberOne, int numberTwo)
    {
    int erg = numberOne * numberTwo;
    return erg;
    }
    int Division (int numberOne, int numberTwo)
    {
    int div = numberOne / numberTwo;
    return div;
    }

    @interface AppDelegate ()

    @property (weak) IBOutlet NSWindow *window;
    @property (weak) IBOutlet NSTextField *repetitions;
    @property (weak) IBOutlet NSTextField *rangeFirstNumber;
    @property (weak) IBOutlet NSTextField *rangeSecondNumber;
    @property (weak) IBOutlet NSTextField *firstNumber;
    @property (weak) IBOutlet NSTextField *calculationSymbol;
    @property (weak) IBOutlet NSTextField *secondNumber;
    @property (weak) IBOutlet NSTextField *successIndikator;
    @property (weak) IBOutlet NSComboBox *calculationMethod;
    @property (weak) IBOutlet NSButton *startButton;
    @property (weak) IBOutlet NSTextField *input;

    @property int calcMethod;
    @property int result;
    @property int inputDone;
    @property int firstNum;
    @property int secondNum;
    @property int corr;
    @property int Loop;
    @property int gameCounter;
    @property NSString *counterOutput;
    @property int loopExit;

    - (IBAction)startComputing:(id)sender;
    - (IBAction)methodOfCalculation:(id)sender;
    - (IBAction)compareResult:(id)sender;

    @end

    @implementation AppDelegate

    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    [_firstNumber setIntegerValue:0];
    [_secondNumber setIntegerValue:0];
    [_successIndikator setStringValue:@""];
    _calcMethod = 0;
    srandom((uint)time(NULL));
    [_input setEnabled:NO];

    }

    - (void)applicationWillTerminate:(NSNotification *)aNotification {
    // Insert code here to tear down your application
    }

    - (IBAction)startComputing:(id)sender {
    _Loop = [_repetitions intValue];
    int firstTop = [_rangeFirstNumber intValue];
    int secondTop = [_rangeSecondNumber intValue];
    _inputDone = 0;
    _gameCounter = 0;
    _counterOutput = @"";
    [_startButton setEnabled:NO];
    [_calculationMethod setEnabled:NO];


    for (int x = 0; x<= _Loop; x++) {
    _firstNum = (int)random() % firstTop + 1;
    _secondNum = (int)random() % secondTop +1;
    if (_calcMethod == 2 && _firstNum < _secondNum){
    int change = _firstNum;
    _firstNum = _secondNum;
    _secondNum = change;
    } else if (_calcMethod == 4){
    _firstNum = _secondNum * _firstNum;
    }
    [_firstNumber setIntegerValue:_firstNum];
    [_secondNumber setIntegerValue:_secondNum];
    [_input setEnabled:YES];
    wait(&(_inputDone));

    }
    [_startButton setEnabled:YES];
    }

    - (IBAction)methodOfCalculation:(id)sender {
    NSInteger item = [_calculationMethod indexOfSelectedItem];
    switch (item) {
    case 0:
    [_calculationSymbol setStringValue:@"+"];
    _calcMethod = 1;
    break;
    case 1:
    [_calculationSymbol setStringValue:@"-"];
    _calcMethod = 2;
    break;
    case 2:
    [_calculationSymbol setStringValue:@"."];
    _calcMethod = 3;
    break;
    case 3:
    [_calculationSymbol setStringValue:@":"];
    _calcMethod = 4;
    break;
    default:
    break;
    }
    }

    - (IBAction)compareResult:(id)sender {

    int numberOne = [_firstNumber intValue];
    int numberTwo = [_secondNumber intValue];
    _result = [_input intValue];
    switch (_calcMethod) {
    case 1:
    _corr = Addition(numberOne, numberTwo);
    break;
    case 2:
    _corr = Subtraction(numberOne, numberTwo);
    break;
    case 3:
    _corr = Multiplication(numberOne, numberTwo);
    break;
    case 4:
    _corr = Division(numberOne, numberTwo);
    break;
    default:
    break;
    }
    if (_result == _corr) {
    _gameCounter += 1;
    _counterOutput = [NSString stringWithFormat:@"Du hast %i von %i Rechnungen richtig gerechnet!", _gameCounter, _Loop];
    [_successIndikator setStringValue:_counterOutput];
    }
    _inputDone = -1;


    }
    @end
  • b.brandl schrieb:

    Habe versucht dies mit einer Warteschleife und einer Variablen zum Ausstieg aus der Schleife probiert, die nach der Kontrolle gesetzt wird. Leider hängt sich dabei das Programm auf. Die Verwendung von wait führt zwar zu einem Erfolg im ersten Durchlauf, dafür schaffe ich aber nicht das wait wieder aufzulösen

    Cocoa-Programme, wie die meisten Programme mit einer GUI übrigens auch, laufen bereits in einer Schleife. Du kannst dir die Warteschleife (+igitt+) also sparen. Stattdessen kannst du alle Operationen in zwei Methoden packen: Eine Methode berechnet die Zufallszahlen und übergibt sie an das UI, und die andere Methode ist eine Actionmethode. Sie liest die Nutzereingabe aus, berechnet das Ergebnis und übergibt es wieder an das UI, was in Cocoa ja dank Bindings kein Aufwand ist. Außerdem ruft sie ggf. wieder die erste Methode auf, um neue Werte anzuzeigen.

    Warteschleifen sind fast immer absolut unnötig.
    „Meine Komplikation hatte eine Komplikation.“
  • Danke für die Antwort. Ich habe aber trotzdem noch ein Problem. Ich habe am UI 2 Auslöser. Einen Startknopf um die Anzahl der Durchläufe zu realisieren und dann wenn die Benutzereingabe erfolgt mit Enter. D. h. Die Nutzereingabe ist ein Programmpunkt des ganzen Ablaufs, der leider nicht zum Anhalten der Schleife führt. Früher war ein Input ein Vorgang im Programm, der auf eine Nutzereingabe gewartet hat. Irgendwie hab ich keinen Plan wie man das realisieren kann.
  • b.brandl schrieb:

    D. h. Die Nutzereingabe ist ein Programmpunkt des ganzen Ablaufs, der leider nicht zum Anhalten der Schleife führt. Früher war ein Input ein Vorgang im Programm, der auf eine Nutzereingabe gewartet hat. Irgendwie hab ich keinen Plan wie man das realisieren kann.


    ich versteh' Dein Problem nicht ganz, vermute aber das Du ein Verständnis-Problem mit dem ereignisgesteuerten Programmablauf hast. Stell' Dir das so vor: Das Cocoa-Framework in einer Anwendung wartet die ganze Zeit in einer Schleife (Nein, keine echte, wir machen ja kein Polling!) auf bestimmte Ereignisse: z.B. der Benutzer klickt auf einen Button, der Benutzer drückt auf eine Taste, der Benutzer macht dieses oder jenes. Wenn so ein Ereignis eintritt, benachrichtigt das Framework deine Anwendung und die kann dann darauf reagieren. Das Prinzip ist bekannt unter "Don't call us, we call you!".

    Deine Anwendung selber muss im Prinzip niemals nicht (zumindest nicht unter normalen Umständen) in irgendeiner Schleife verharren um Benutzereingaben abzufangen.

    Jetzt klarer?

    edit: Wenn Du mit "früher" z.B. die Input-Funktionen von good-old-plain-c (z.B. scanf) meinst, dann musst Du dich von dem Gedanken schnell entfernen. So geht's nicht, wenn das ganze GUI-basiert ist. Zumindest nicht auf denen GUIs, mit denen ich bisher gearbeitet habe. Alles ereignis-basiert.

    schönen Gruß

    gandhi