Selbstgemachte Array suche



  • Ok jetzt hab ich es auch gesehen, war wirklich ein winziger Fehler.
    Danke für die Hilfe.

    Edit:
    Mir ist beim Probelauf grade ein weiterer Bug aufgefallen.
    Bei dem Programm wie es dort oben steht, hängt es sich nach der Eingabe der ersten Zahl völlig auf.
    Soll heißen das die Komandozeile auf keine eingaben mehr reagiert.
    Sieht jemand in diesen Programm den fehler?
    MFG Blade



  • Hallo,

    Was willst du denn hiermit erreichen?

    while (pos <40, striger==0)
    


  • Die Eingabe des Rechners läuft etwas störrisch ab.
    Man gibt eine Zahl ein drückt Enter, dann gibt man ein Rechenzeichen ein und drückt wieder Enter und so weiter.
    Es gibt außerdem eine begrenzung für die länge einer Rechenaufgabe und zwar 20 Zahlen mit 19 Rechenzeichen. Sprich läuft die Eingabeschleife nur 39 mal.
    Der Striger ist ein Wert den die Funktion ssuche auf 1 setzten wird, wenn die ssuche im Rechenzeichen array den char 's' findet und damit die Eingabeschleife frühzeitig beenden kann.

    Soweit meine komplexe Logik.

    MFG Blade



  • blade1982 schrieb:

    und mit " wäre es ein Komentar.

    Nach der Aussage wäre "s" ein Kommentar? Kommentare beginnen entweder mit // und greifen dann nur für den Rest der aktuellen Zeile oder mit /* und müssen mit */ geschlossen werden. "s" wäre ein Stringliteral.

    Deine Schleife sollte mehrere Vergleiche durch "UND" (&&) oder "ODER" (||) verbinden. Bei deiner Schleife wird pos<40 gar nicht weiter betrachtet. Am Ende zählt das Resultat das striger==0 liefert für den Abbruch oder das Weiterlaufen deiner Schleife (Minimalbeispiel):

    int i=0;
    int pos=45;
    int b=0;
    while(pos<40, b==0) { // && oder || statt ','
      cout << i++ << endl;
      if(i==10) b=1;
    }
    

    Die Schleife läuft solange, bis b einen anderen Wert als 0 hat. Der Wert und Typ des Gesamtausdrucks ist der Wert und Typ des (am weitesten) rechts stehenden Teilausdrucks. In diesem Fall b==0. Da wird pos<40 zwar ausgeführt, aber am Ende nicht weiter betrachtet.

    Greetz



  • Ich weiß grade nicht wo das hier hinführt, aber die Mainfunktion ist soweit richtig und funktioniert auch so wie sie es soll.
    Das problem ist erst aufgetaucht als die Funktion ssuche eben nach den char s suchen soll.
    Die ssuche wird bei jeder Rechenzeicheneingabe gestartet.
    Wenn man aus der Main Funktion den ssuche Aufruf auskommentiert funktioniert die Main so wie es gewollt war.
    Daher vermute ich das die Funktion ssuche immer noch einen (logischen) Fehler enthält.

    P.S. pos < 40 ist ja eine Bedingung unter der die while schleife nur laufen darf. Weil die while Schleife bei jeden durchlauf die pos um 1 erhöht läuft diese auch nur max. 39, eben wegen der Bedingung pos < 40.

    MFG Blade



  • Du brauchst mir die Funktionsweise einer while-Schleife nicht erklären. Deine Bedingung in der While-Schleife lässt pos<40 vollkommen außer acht. Wenn deine Schleife immer bis maximal 39 läuft, ist das nur Zufall, weil irgendwie striger ungleich 0 wird, wenn pos die 39 erreicht.
    In deiner anderen Schleife ist diese Bedingung genau andersherum. Da hat striger==0 keine Wirkung, aber i<40 hat jedoch eine.

    Kein Wunder das es nicht funktioniert. Du beginnst deine Indizierung mit pos=1 in main. Indizierung beginnt in C++ immer bei 0. Du liest also in zeichen[pos] ein Zeichen ein. Da greifst du aber scheinbar immer mit einer geraden Zahl drauf zu. Im ersten Durchlauf also pos[2]. In deiner Suche (ssuche()), beginnst du aber mit pos=1 und erhöhst dann immer um 2. Damit erwischst du immer nur die Stellen im Array, die kein Zeichen haben.

    // Edit:
    Dadurch das du immer auf eine Stelle zugreifst, die eigentlich immer ungleich 's' sein müsste, wird striger eigentlich auch nie 1. Dadurch wird deine while-Schleife in main nie abgebrochen und du greifst irgendwann auf ungültige Speicherbereiche zu (könnte den Absturz der Anwendung erklären).

    Greetz



  • Stimmt, gute Tips! Ich habs nochmal verkürzt und nun geht es.
    Man muss wirklich gut aufpassen das man da nicht iwo ne kleinigkeit verschlampt.
    P.S. Gibt es eingelich ein Befehl in C++ der das Programm beendet? Also wenn z.b. im Zahlenarray ein a gefunden wird, das das Programm nach einer Fehlerausgabe mit cout das Programm anhält?

    MFG Blade

    Hier der neue Code:

    #include <iostream>

    using namespace std;

    char zeichen [39]={0};
    double zahlen [39]={0};
    int striger=0;
    int ztriger=0;
    void ssuche();
    void zsuche();
    int pos=0;

    int main()
    {
    cout << "Bitte geben sie eine beliebige Rechnung ein" <<endl;
    cout << "Erlaubte Zeichen sind: 0-9,+,-,*,/" <<endl;
    cout << "Sowie 's' um die Eingabe zu beenden" <<endl;
    while ((pos <39) && (striger==0))
    {
    if (pos%2==0)
    {
    cout << "Bitte geben sie als ";
    cout << 1+pos;
    cout << ". Zahl ein: ";
    cin >> zahlen[pos];
    zsuche ();
    pos=pos+1;
    }
    else
    {
    cout <<"Bitte geben sie als ";
    cout <<1+pos;
    cout <<". Rechenzeichen ein: ";
    cin >> zeichen[pos];
    ssuche();
    pos=pos+1;
    }
    }
    system ("pause");
    }
    void ssuche ()
    {
    char temp1=zeichen[pos];
    if (temp1 == 's')
    striger=1;
    }

    void zsuche ()
    {
    double temp2=zahlen[pos];
    if (temp2 == 0)
    ztriger=1;
    }



  • Könntest du bitte Einrückungen und Code-Tags verwenden. So ist dein Code nur schlecht lesbar.



  • Nicht Befehl, aber eine Funktion exit(), die einen Integer entgegen nimmt. Dies entspricht dem Fehlercode mit dem die Anwendung beendet wird, wie der Rückgabewert in main.

    Fehlerausgaben macht man üblicherweise mit cerr (ungepuffert), statt mit cout.

    Greetz


  • Administrator

    Vellas schrieb:

    Nicht Befehl, aber eine Funktion exit(), die einen Integer entgegen nimmt. Dies entspricht dem Fehlercode mit dem die Anwendung beendet wird, wie der Rückgabewert in main.

    Ganz schlechte Empfehlung. exit terminiert das Programm auf der Stelle, es werden keine Destruktoren aufgerufen und gibt dadurch keine Ressourcen mehr frei.

    Deutlich besser ist, wenn du in der main Funktion ein return <irgendeineZahl> machst, wobei <irgendeineZahl> 0 ist, falls kein Fehler war oder ein Errorcode.

    Falls du irgendwo im Programm (also in anderen Funktionen) bist, dann wirft man eine Exception. Diese kann man in main abfangen und einen Errorcode ausgeben oder man lässt sie durchlaufen, dann stürzt das Programm ab, aber alle Destruktoren werden aufgerufen.

    http://magazin.c-plusplus.net/artikel/Exception-Handling
    http://magazin.c-plusplus.net/artikel/Modernes%20Exception-Handling%20Teil%201%20-%20Die%20Grundlagen
    http://magazin.c-plusplus.net/artikel/Modernes%20Exception-Handling%20Teil%202%20-%20Hinter%20den%20Kulissen

    Grüssli



  • Das ist mir klar. Ich war/bin allerdings der Meinung, dass er vielleicht vorher andere Sachen festigen sollte, bevor er wieder mit neuen Sachen (Exceptions) konfrontiert wird.

    Greetz



  • Vellas schrieb:

    Das ist mir klar. Ich war/bin allerdings der Meinung, dass er vielleicht vorher andere Sachen festigen sollte, bevor er wieder mit neuen Sachen (Exceptions) konfrontiert wird.

    Dann benutzt er eben Returnwerte. Immer noch besser, als sich rücksichtlose Mechanismen wie exit() anzugewöhnen. Zumal man sich - gerade als Anfänger - der Konsequenzen oft gar nicht bewusst ist. Ohne Dravere hätte er vielleicht nie erfahren, was exit() gefährlich macht...



  • Wenn wir schon dabei sind, dann sollte man ihm an dieser Stelle auch noch von globalen Variablen abhalten. Ist auch böse und kann ebenfalls schnell mal ins Auge gehen. Und eventuell, dass system() auch nicht sehr ratsam ist (mal abgesehen davon das dafür die cstdlib eig. fehlt). Ein Pause kann man auch anders nachbilden (und wenn man die Anwendung statt mit einer beliebigen Taste mit Enter beenden muss).

    Greetz



  • Finds wirklich nett wieviel Sorgen ihr euch alle um mich macht :). Wohl auch nicht ganz unbegründet.
    Wobei die exit Funktion schon recht hard ist, im Grunde sollte einfach eine Fehlermeldung ausgegeben werden und das Programm nicht abstürzen bzw. einfach wieder von vorn beginnen.

    Anderes Thema:
    Ich wollte zwischen drin eine double Zahl vergleichen:

    double array [1]='0'
    ihr wisst schon was jetzt kommt, auch wenn an Postion 1 im array eine Null steht wird dieser Ausdruck nicht True, scheiß ungenauigkeit (wie ich eben gelernt habe).

    Was wäre nach euer Meinung der beste Weg ein Double Wert mit einer ganzen Zahl zu vergleichen?

    Ich hab schon dran gedacht einfach eine Art Grenzwert zu machen:
    double array [1]='0.0000000000000000001'
    wobei hier natürlich nicht ausgeschlossen sein kann das im array an der stelle noch eine längere komazahl steht die natürlich nicht Null ist.
    😃

    MFG



  • Normalerweise nimmt man dafür ein delta.

    z.B hier:
    http://www.cplusplus.com/reference/clibrary/cfloat/


  • Administrator

    drakon! Doch nicht die C Makros 😃
    http://www.cplusplus.com/reference/std/limits/numeric_limits/

    @blade1982,
    Die 0 Darstellung von double sollte aber eigentlich ziemlich genau sein.
    Könnte es sein, dass du das folgende geschrieben hast?

    double value = '0';
    // statt
    double value = 0.0;
    

    '0' ist nämlich nicht 0, sondern der Buchstabe 0 und dieser hat normalerweise nicht den Wert 0.

    Grüssli



  • Ja habe ich ;), somit ist es überflüssig sich gedanken um den Vergleich zu machen ?


  • Administrator

    blade1982 schrieb:

    Ja habe ich ;), somit ist es überflüssig sich gedanken um den Vergleich zu machen ?

    Wenn double wirklich genau 0 ist, dann ist es genau 0, denn 0 kann ein double genau darstellen 😃
    Im allgemeinen ist es aber immer sinnvoll sich Gedanken über die Vergleiche bei Gleitkommazahlen zu machen. Denn nach verschiedenen Rechenoperationen, wenn das Ergebnis wieder 0 ergeben sollte, muss das nicht unbedingt der Fall sein 😉

    Im allgemeinen sagt man eigentlich, dass man double und float Werte nicht auf Gleichheit prüfen sollte, sondern immer mit grösser- oder kleiner-als Vergleichen. Wenn man doch mal auf Gleichheit prüfen sollte, dann ist es eben sinnvoll das Delta hinzu zu nehmen.

    Grüssli



  • Und wieder was gelernt.
    Das mit dem double 0 vergleich mit 0.0 hab ich nicht Ansatzweise im Internet gefunden. Könnte aber auch an meinen Suchwort gelegen haben, naja.


Anmelden zum Antworten