1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

C++: while do-Schleife mit OR-Inhalt

Dieses Thema im Forum "OS X-Developer" wurde erstellt von Cyrics, 11.11.05.

  1. Cyrics

    Cyrics Neuer Berner Rosenapfel

    Dabei seit:
    01.04.05
    Beiträge:
    1.975
    Hey,

    ich werkel die ganze Zeit an einer while-do-Schleife in C++ rum, und ich möchte zwei Bedingungen deklarieren, wobei beide zusammen oder eine von beiden den Abbruch bewirken können:
    Code:
        
        while ((!cin.eof())||(!ende)) { 
                           do { // Eingabe
                              ....;
                              } while (i<j);
                              
                           if (i=j) // Ausgabe
                              {
                              for(i=0;i<j;i++) 
                                                {
                                                ...; 
                                                }
                                                
                              }
                           ende=true;
                           }
    
    Abbruch soll wie gesagt Strg+Z sein, oder wenn das ende erreicht ist und damit auf true gesetzt wird.
    Beide Bedingungen für sich funktionieren, aber es funktioniert einfach nicht, dass nur eine von beiden anspringt. Soll heissen, dass ende zwar true ist, aber nicht abbricht, da cin.eof nicht aktiviert.

    Ich hab es nun mit dem bitweisen OR (|) und dem logischen OR (||) probiert, nichts funktioniert... Ideen?!

    Danke! :)
     
  2. Squart

    Squart Pomme Etrangle

    Dabei seit:
    29.01.04
    Beiträge:
    910
    Das ist hier falsch. Sobald nur eine beider Aussagen nicht erfüllt ist - was ja meistens ist - wird die Schleife ausgeführt. Du solltest eher
    Code:
    while (!cin.eof() && !ende)
    benutzen.
     
  3. commander

    commander Baldwins roter Pepping

    Dabei seit:
    25.02.04
    Beiträge:
    3.210
    Äh, ma sehn, ob ich dich richtig verstehe:

    Falls cin.eof() == true oder ende == true ist, oder beide, soll die Schleife abbrechen... oder?

    Also:

    while(!cin.eof() && !ende) {}

    Nur wenn der gesamte Ausdruck true ist, wird weitergemacht. Sollte eine der beiden Konditionen true werden, also negiert damit false, wird der gesamte Ausdruck false und die Schleife bricht ab.

    In Deinem Code passiert genau das Gegenteil, solange einer von beiden false (also negiert true) ist, wird weitergemacht, da Du mit OR hantierst.

    Gruß,

    .commander
     
  4. Cyrics

    Cyrics Neuer Berner Rosenapfel

    Dabei seit:
    01.04.05
    Beiträge:
    1.975
    ohje! ich sitz da 2 stunden vor dem Problem und kann mich nicht um den Rest kümmern, und da fiel mir das auch gerade vor 1 Minute auf!!
    da war der Gedankenfehler mit der Schleife, dass while ja auch nur so lange läuft wie die beiden Bedingungen nicht aktiviert sind... daher brauch ich ja beide bloss verneinen und gleich mit && verknüpfen...

    mensch mensch... peinlich peinlich :(
    schöne kostbare Zeit!

    VIELEN DANK!
    *leise verkrümel und hoff, dass nun alles wenigstens läuft*
     
  5. MacApple

    MacApple Lord Grosvenor

    Dabei seit:
    05.01.04
    Beiträge:
    3.470
    Probiere es doch einfach mal mit einem UND (&&).

    MacApple

    Edit: Hätte wohl erst einmal die Anzeige aktualisieren sollen. :)
     
  6. commander

    commander Baldwins roter Pepping

    Dabei seit:
    25.02.04
    Beiträge:
    3.210
    Falls ich vor einem kniffeligem Problem sitze und nicht weiterkomme, gehe ich zu einem meiner Kollegen - die kennen das schon - und sage: "Ich muss Dich jetzt mal kurz zuschwallen, tu wenigstens so, als ob Du zuhörst.."

    Allein durch das beschreiben des Problems verlässt man die bisherige Perspektive und muss die vorhandenen Daten anders aufbereiten - und schon fällts einem in 90% der Fälle wie Schuppen von den Augen.

    Das geht soweit, dass ich manchmal nur dazu komme, einmal tief Luft zu holen :" Aaaalssooo, pass auf: äh, ok! Ich habs! Danke für die Hilfe!"

    ;)

    Gruß,

    .commander
     
  7. Cyrics

    Cyrics Neuer Berner Rosenapfel

    Dabei seit:
    01.04.05
    Beiträge:
    1.975
    so ist das meistens bei mir... ich scheiter manchmal an den kleinsten Dingen und sitz dann stundenlang davor... und kaum erzähl ich das Problem anderen Personen ist die Lösung plötzlich sooo einfach...

    naja... Programm läuft dafür super, alles funktioniert... ich bin Glück. 6 Stunden Arbeit haben sich gelohnt ;)

    nochmals vielen Dank *g*

    PS: wird sicher öfter passieren sowas mit mir...
     
  8. Cyrics

    Cyrics Neuer Berner Rosenapfel

    Dabei seit:
    01.04.05
    Beiträge:
    1.975
    ich will für mein kleines Problem kein neuen Thread aufmachen... aber ich hab nun mein Programm sowohl unter Linux als auch unter Windows kompiliert gehabt und es gab keine Probleme...

    dann hatte ich gestern abend noch auf meinen Mac mit dem neuen Xcode 2.2 probiert...

    und da kommt dann folgende Fehlermeldung:
    Code:
    [Session started at 2005-11-12 19:53:17 +0100.]
    ZeroLink: unknown symbol '_stdscr'
    
    c++ has exited due to signal 6 (SIGABRT).
    Ansonsten hier mal mein Programm... ich weiss einfach nicht was mit stdscr gemeint ist :(

    Code:
    #ifdef WIN_32
    #include <conio.h>
    #else
    #include <curses.h>
    #endif
    #include <iostream>
    #include <iomanip>
    #include <stdio.h>
    #include <math.h>
    
    using namespace std;
    
    int main()
    {
        int i=0, mehrwertsteuer=16, j=0;
        bool ende;
    	double gesamt, gesamtsumme;
        struct styp {
               long nummer;
               char name[30];
               int menge;
               float preis;
               }; 
               
        
        cout <<"Artikeleingabe"<<endl;
        cout <<"Wieviel Artikel sollen eingegeben werden? ";
        cout <<"\nArtikelanzahl: "; cin>> j;
        cin.ignore(255,'\n');
        cout <<"Abbruch mit <Strg>+Z moeglich!\n";
        cout <<"Preisangaben nur mit 2 Kommastellen und mit Punkt als Komma\n";
        styp Artikel[i];
        ende=false;
    
    
        while ((!cin.eof()) && (!ende)) { 
                           do { // Eingabe
                              i++;
                              Artikel[i].nummer = i;
                              cout<<"\nArtikelnummer: "<< Artikel[i].nummer<< endl;
                              cout<<"Artikelname: "; cin.getline(Artikel[i].name,30);
                              cout<<"Artikelmenge: "; cin >> Artikel[i].menge;
                              cout<<"Artikelpreis in Euro: "; cin >> Artikel[i].preis;
                              cin.ignore(255,'\n');
                              gesamtsumme=gesamtsumme+Artikel[i].preis;
                              cout <<endl <<endl;
                              } while (i<j);
                            
                            
                              cout << setw(15)<<"Artikelnr";
                              cout << setw(15)<<"Bezeichner";
                              cout << setw(15)<<"Anzahl";
                              cout << setw(15)<<"Preis in Euro"<<endl;
                            i=0;
                            do 
                              {
                              i++;
                              cout.setf(ios::right); // Rechtsbuendig
                              cout  << setw (15)<< Artikel[i].nummer;
                              cout  << setw (15)<< Artikel[i].name;
                              cout.setf(ios::left); // Linksbuendig
                              cout  << setw (15)<< Artikel[i].menge;
                              cout.precision(2); // Kommastellen 
                              cout << setw (15)<< Artikel[i].preis<<endl;                              
                              } while (i<j);                                            
                           ende=true;
                           };
        gesamt=gesamtsumme+gesamtsumme*(mehrwertsteuer/100);
        cout.setf(ios::left);                   
        cout <<"\nMehrwertsteuer "<<mehrwertsteuer<<"%:";
        cout.setf(ios::right); 
        cout << setw(45) <<"Gesamtsumme in Euro: "<<gesamtsumme;
        cout << setw(60) <<"\n inkl.Mehrwertsteuer: "<<gesamt;
                           
        cout <<"\nWeiter mit beliebiger Taste..." <<endl;
        getch();
        return 0;
    }
    
    ich weiss jetzt nicht mal ob mein abgeänderter Code überhaupt noch unter Linux/Windows funktioniert... hab ihn nämlich noch abgeändert gehabt...

    Könnt ihr mir also sagen wo XCode das Problem sieht?!
    Das lustige ist ja auch, dass der Code noch gestern auf der Konsole mit g++ funktionierte. Nun wo XCode 2.2 aber installiert ist, klappt es nicht mehr unter XCode und auch nicht mit g++...

    Edit:
    hier noch die Fehlermeldung vom g++-Compiler
    Code:
    /usr/bin/ld: Undefined symbols:
    _stdscr
    _wgetch
    collect2: ld returned 1 exit status
     
    #8 Cyrics, 12.11.05
    Zuletzt bearbeitet: 12.11.05
  9. Demo

    Demo Süssreinette (Aargauer Herrenapfel)

    Dabei seit:
    02.04.04
    Beiträge:
    411
    Wenn Du die curses Bibliothek in dein Xcode Projekt einbindest sollte es klappen.
    Oder Du kompilierst das ganze von Hand und linkst gegen die curses Bibliothek.

    etwa so
    Code:
    g++ datei.cpp -o myapp -lcurses
    
     
  10. Cyrics

    Cyrics Neuer Berner Rosenapfel

    Dabei seit:
    01.04.05
    Beiträge:
    1.975
    aber die hab ich doch per #include und der ifdef-else-Bedingung gesetzt?!
    Hatte es auch ausprobiert nur die curses und die conio und die if-else-Bedingung auszukommentieren. Bringt beides nicht den nötigen Erfolg.

    Wenn ich unter dem g++ das getch() in cin.get austausche, dann funktioniert es mit dem g++, und er lässt den Fehler mit der stdscr unter den Tisch fallen.
    Aber XCode reitet daraufrum und will das nicht zu ende kompilieren :(
     
  11. Demo

    Demo Süssreinette (Aargauer Herrenapfel)

    Dabei seit:
    02.04.04
    Beiträge:
    411
    Ich glaub Du verstehst die Problematik nicht. Die curses.h ist zwar in deinem quelltext drin, aber nicht in deinem Xcode Projekt. Je nachdem, was dort (in dem Xcode Projekt) fuer Bibliotheken angeben sind, startet Xcode entsprechend den Kompiliervorgang mit den jeweiligen Optionen.

    Du kannst das ja mal per Hand kompilieren, dann wirst sehen was ich meine. Halte ich so oder so fuer die bessere Wahl, dann sieht man was benoetigt wird respektive der ganze Ablauf funktioniert. Und bei groesseren Sachen kann man sich dann ein Makefile schreiben.
     
  12. Cyrics

    Cyrics Neuer Berner Rosenapfel

    Dabei seit:
    01.04.05
    Beiträge:
    1.975
    Pluto:~/c++ User$ g++ main.cpp -o myapp -lcurses
    main.cpp:4:18: error: curses: No such file or directory
    main.cpp: In function 'int main()':
    main.cpp:80: error: 'getch' was not declared in this scope

    und ich glaub ich hab dich jetzt verstanden. Aber ist halt ein bissel verwirrend eine Bibliothek einzulesen, die eigentlich schon im include-Ordner hockt und auch per include noch eingebunden wird... dann muss ich erstmal gucken wie ich bei XCode noch die curses.h einbinden kann.
    Muss ich das dann bei jedem Projekt tun, oder ist dies eine einmalige Sache?
     
  13. tjp

    tjp Baldwins roter Pepping

    Dabei seit:
    07.07.04
    Beiträge:
    3.250
    Mit dem Include werden nur die in der entsprechenden Include Datei deklarierten Symbole in der jeweiligen Übersetzungseinheit bekannt gemacht. Wenn man nun eine ausführbare Datei haben will, dann müssen alle Übersetzungeinheiten mit den Definitionen der Symbole zusammengelinkt werden. Libraries dienen bloß dazu, daß man Übersetzungseinheiten nicht ständig statisch in Programme linken muß. Der C++ Compiler bindet von sich nur ein paar Libraries ein, C++ Laufzeit Library, C++ Standard Library und C Standard Library. Alle anderen mußt Du von Hand in das Projekt aufnehmen.
     
  14. Cyrics

    Cyrics Neuer Berner Rosenapfel

    Dabei seit:
    01.04.05
    Beiträge:
    1.975
    soweit hatte ich das dann auch verstanden.
    Problem bzw. Frage ist dann: wie binde ich diese ins Projekt ein?
    XCode hat irgendwie die Eigenart undurchschaubar und überkomplex zu sein. Ersteres resultiert von zweiterem. Ich seh einfach keien Möglichkeit :(

    Ich hab schon die Headerdatei curses.h ins Projekt mit reingezogen und sie wurde auch importiert, aber keine Besserung.

    Wenn ich es wie Demo schrieb mit dem Befehl per Konsole anhängen will, bringt er den oben genannten Fehler...

    es scheitert also nicht am Verständnis sondern am Unvermögen :-c
     
  15. tjp

    tjp Baldwins roter Pepping

    Dabei seit:
    07.07.04
    Beiträge:
    3.250
    Wenn Du auf der Kommandozeile arbeitest und den g++ nutzt dann mußt Du als ersters, das Verzeichnis ermitteln in dem sich die betreffende Library befindet. Dabei mußt Du darauf achten, ob es sich um eine statische Library (.a), dynamische (.dylib unter MacOS X sonst meist .so) oder ein FrameWork handelt.

    Wenn sich die Library nicht im Standardsuchverzeichnissen befindet, dann mußt Du das betreffende Verzeichnis in den Suchpfad aufnehmen. Für ersteres laß dir alle Optionen mit "g++ -v --help | less" auflisten, ich weiß jetzt nicht mehr welche Option es war. Ich glaube ist müßte die Option für den Spec Dump sein.

    Ok, willst Du "libcurses.dylib" linken gibst Du auf der Kommandozeile die Option "-lcurses" an. Ist sie nicht im Suchpfad mußt Du "-Lsuchpfad" davor schreiben. Wenn statische Libraries linken willst mußt Du "-static" vor die Library schreiben. Aber aufpassen, anschließend werden alle nachfolgendes Libraries ebenfalls statisch gelinkt. Den dynamischen Linkmodus bekommt man wieder mit "-dynamic". Genaures steht in der Doku zum "ld". Wenn Du C++ schreibst, rufst Du zwar zum Linken immer den g++ auf, aber ettliche Optionen werden 1:1 an den "ld" durchgereicht. Daher ist es unumgänglich beide Dokus zu lesen.

    Für XCode lies Dir die Doku durch. Ich nutze noch 10.2.x, da gab es nur den ProjetBuilder. Bei dem kann man zu jedem Projekt zusätzliche Libaries hinzufügen. Die dann auch dazugelinkt werden. Aber wie es genau gemacht wird, steht in der Anleitung. Ich nutze die IDE eigentlich nur für kleinere Cocoa Sachen und das selten. C++ Programme schreibe ich fast ausschließlich auf und für Linux & Solaris.
     
  16. Binary

    Binary Gast

    Hi, stand hier die tage noch aber ich finde es nicht wieder:

    Du kannst zu Xcode Unix-Libs per drag & drop hinzufügen wie andere
    Frameworks auch. Das Problem ist nur, dass die Verzeichnisse
    nicht sichtbar sind.
    Gehe einfach im Finder auf Gehe zu ->Gehe zum Ordner ...
    da tippst du dann "/usr/lib" (oder wo deine libs liegen) und ziehst
    dir den Ordner in die Seitenleiste. Wenn du jetzt in Xcode das nächste
    mal "Add Framework" machst kannst du über die Seitenleiste die
    .dynlibs etc. aus wählen.

    lg
     
  17. Cyrics

    Cyrics Neuer Berner Rosenapfel

    Dabei seit:
    01.04.05
    Beiträge:
    1.975
    Hey,

    Danke für den Tipp! Ich weiss nur nicht welche Seitenleiste du meinst :(
    Ordner etc. hab ich gefunden. Und ich schätze mal du meinst die Seitenleiste von der Projekt-Datei. Aber dort ist der lib-Ordner nicht ablegbar. Überhaupt ist er nirgends per drag&drop hinziehbar außer mitte in die CPP-Datei.

    PS: hab auch ein neues Problem, bzw. eine kleine Verständnisfrage:
    gibt es unter C++ auch Prozeduren?!
    Also ich kenn ja Funktionen und Prozeduren. Der kleine aber feine Unterschied ist, dass Funktionen nur in der funktion ermittelte Werte rückgeben kann und als Variable in der Art funktioniert. Eine Prozedure ist dagegen ja schon fast ein eigeneständiges für sich laufendes Programm, dass seine eigene Deklaration und Variablenübergabe aufweist.

    Ich such nun dringend eine Möglichkeit eine Prozedure einzubinden! Wenn ich es per Funktion mache, überspringt er die Funktion förmlich und liefert keinen Wert zurück.
     
  18. tjp

    tjp Baldwins roter Pepping

    Dabei seit:
    07.07.04
    Beiträge:
    3.250
    C++ kennt keine Trennung zwischen Prozedur und Funktion.
    Es gibt nur Funktionen, die können müssen aber keinen Rückgabewert haben. Paramter an eine Funktion werden, wenn nicht anders spezifiziert "per value" übergeben, d.h. es wird immer eine lokale Kopie erzeugt. Das ist nur dann nicht der Fall, wenn man Variable per Referenz übergibt, dann können Variablen innerhalb der Funktion verändert werden. Die dritte Möglichkeit ist es Zeiger auf Werte zu übergeben.

    Alle drei Variante ("by value", "by reference" und "by pointer") lassen sich mit dem Ausdruck "const" kombinieren, d.h. der Wert läßt sich dann nicht verändern.

    Beispiele
    Code:
    #include <iostream>
    int const foo () {
       return -1;
    };
    
    void foo2 (int i) {
       ++i;
    };
    
    int const foo3 (int const i) {
       return i + 3;
    };
    
    void foo4 (int& i) {
       ++i;
    };
    
    int main () {
       int p = 0;
    
       foo2 (p);
       foo4 (p);
       int q = foo3(p);
       int p = foo();
    
       std::cout << "p: " << p << "\nq: " << q << << std::endl;
    }
    
     
  19. Cyrics

    Cyrics Neuer Berner Rosenapfel

    Dabei seit:
    01.04.05
    Beiträge:
    1.975
    hmmm, sehr merkwürdig.
    meine Funktionen würden ja dann in die "per reference"-Klasse gehören. Sie werden jedoch komplett übergangen und nicht ausgeführt. Am besten ich poste mal einen Aussschnitt aus dem Skript (das ganze ist leider etwas länger geworden).

    die Funktion:
    Code:
     
    int Zufallshoehenseingabe(int zufall) { 
        cout<<"\n Hoehe der bestimmenden Zufallszahl: "; cin>>zufall; 
        return(zufall); 
    }
    Der Funktionsaufruf, der ausgeführt wird und komplett übergangen ohne auf den cin-Befehl einzugehen:
    Code:
    { int Zufallshoehenseingabe(int zufall); } break;
    
    Oder hab ich das Problem das Eingabe/Ausgabe-Befehle etc. nicht in Funktionen akzeptiert werden, sondern nur Rechenoperationen?!
     
  20. tjp

    tjp Baldwins roter Pepping

    Dabei seit:
    07.07.04
    Beiträge:
    3.250
    Da hast Du Dir aber kräftig selbst das Bein gestellt!
    Du deklarierst eine int Variable Zufallshoeheneingabe initialisierst diese mit dem Wert von zufall, das Du temporär erzeugst.

    Du kannst die Funktion in einer der drei Varianten aufrufen.
    Code:
    Zufallshoeheneingabe (zufall);
    int x = Zufallshoeheneingabe (zufall);
    int y (Zufallshoeheneingabe(zufall));
    
    Im ersten Fall wird der Rückgabewert verworfen, in den beiden letzten Fällen wird jeweils eine neue int Variable mit dem Rückgabewert initialisiert.

    Noch ein Tipp, laß die () um das return Statement weg. Das ist kein Funktionsaufruf!
     

Diese Seite empfehlen