zahlen von klein nach groß sortieren



  • @ manni66

    ja aber wenn ich int main () schreibe, dann bekomm ich ein fehler. nur wenn ich void main schreibe, ist der fehler weg.

    @ pyhax
    vielen dank für diesen einfachen programm. den kan man auch ganz leicht auf 5 zahlen oder mehr erweitern.



  • Gugelmoser schrieb:

    Swordfish schrieb:

    Ok. Gibt's dann einen portablen, standardkonformen Weg, cin nach fail() zu restaurieren?

    cin.clear();
    

    cin.clear() leert aber den puffer IMHO nicht...



  • Mohamedyarub schrieb:

    ja aber wenn ich int main () schreibe, dann bekomm ich ein fehler. nur wenn ich void main schreibe, ist der fehler weg.

    Was denn für einen Fehler?


  • Mod

    Swordfish schrieb:

    Ok. Gibt's dann einen portablen, standardkonformen Weg, cin nach fail() zu restaurieren?

    Na, clear(). Wobei du dann aber wahrscheinlich noch Zeichen verwerfen willst. Dann kommt's drauf an, wieviele du verwerfen möchtest. Ich verwerfe ja gerne nur das nächste Zeichen, andere eine ganze Zeile. Aber auf jeden Fall nicht rdbuf()->in_avail() viele und auch nicht sync(). Denn in_avail() gibt die Anzahl der Zeichen, die noch mindestens im Stream sind. Ein standardkonformes Verhalten (welches auch durchaus sehr oft anzutreffen ist, da technisch gar nicht anders möglich) ist 0. Ähnlich bei sync(), welches eigentlich eher für ostreams gedacht ist. In der Windowskonsole trifft es sich eben, dass sync gerade so funktioniert wie du es dir denkst, aber standardkonform und durchaus nicht unüblich ist ebenfalls, dass einfach nix passiert. Willst du eine ganze Zeile verwerfen, macht man daher clear() und dann ignore(std::limitsstd::streamsize::max(), '\n'). Das funktioniert garantiert und mehr ist gar nicht nötig. Daher wundert mich auch dein Programm ein bisschen, denn diese Elemente hast du schon drin und mir ist nicht ganz klar, wozu die ganzen Zusätze überhaupt gut sein sollen.



  • std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    

    Das ist Implementation defined SeppJ 😕


  • Mod

    Gugelmoser schrieb:

    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    

    Das ist Implementation defined SeppJ 😕

    Nein, das sync() und in_avail(). Wobei implementation defined nicht exakt ausgedrückt ist. Im Standard steht ein vorgebenes Verhalten (siehe mein vorheriger Beitrag), aber dieses Verhalten entspricht nicht unbedingt dem das Swordfish für sein Programm benutzt.



  • Deine Analyse von sync() ist nicht ganz korrekt, aber sync() ist im Standard auch nicht besonders hilfreich definiert. std::basic_ostream hat keine Methode sync(), sondern stattdessen flush(). std::basic_istream::sync() und std::basic_ostream::flush() sind so definiert, dass sie rdbuf()->pubsync() aufrufen, und std::basic_streambuf::pubsync() ruft seinerseits std::basic_streambuf::sync() auf (NVI).

    Bei std::basic_streambuf::sync() handelt es sich um eine virtuelle Funktion, die vom Benutzer in abgelittenen Klassen überschrieben werden kann, und wenn er das tut, erhält std::basic_istream::sync() einen Sinn. Allerdings überschreiben alle Standard-Streambuffer std::basic_streambuf::sync() in einer Art und Weise, die nur für Ausgabeströme Sinn ergibt; sofern man also std::cin nicht vorher einen eigenen Streambuffer andreht, der sync() in passender Weise redefiniert, ist das Verhalten von std::cin.sync() nicht definiert.





  • SeppJ schrieb:

    [...] Daher wundert mich auch dein Programm ein bisschen, denn diese Elemente hast du schon drin und mir ist nicht ganz klar, wozu die ganzen Zusätze überhaupt gut sein sollen.

    Bei einer Eingabe von Hausnummer "4a" für einen Integer liefert cin die 4 und das 'a' bleibt im Puffer, das failbit bleibt ungesetzt. Ich wollte in if( std::cin.rdbuf( )->in_avail( ) && std::cin.get( ) != '\n' ) { (falls noch irgendwas außer einem '\n' im Puffer) das failbit manuell setzen und den Puffer - an dieser Stelle offenbar standardkonform 😉 - leeren.
    Daß std::cin.rdbuf()->in_avail() "nur" die Anzahl der mindestens im Puffer vorhandenen Zeichen liefert, habe ich nicht gewusst.



  • Gibt es eigentlich in C++11 irgendetwas um dieses Problem zu umgehen?



  • pyhax schrieb:

    Gibt es eigentlich in C++11 irgendetwas um dieses Problem zu umgehen?

    Gilt deine Frage Swordfishs vorherigem Post? Wenn du schauen willst, ob noch Zeichen im Puffer sind, dann nimmst du cin.peek() . Ist dies der Fall, dann leerst du den Puffer, ansonsten nicht.

    edit: Obwohl, wenn nichts im Puffer steht, wird auf eine Eingabe gewartet, ist auch doof 😞 .



  • Wieso Problem? Beim Einlesen der nächsten Zahl wird dann halt 'a' gefunden und das Failbit gesetzt.

    Ansonsten hindert dich nichts daran, ganze Token einzulesen und per stringstream zu parsen:

    template<typename T>
    std::istream &greedy_parse(std::istream &in, T &result) {
      std::string s;
    
      in >> s;
    
      std::istringstream parser(s);
    
      parser >> result;
      parser.get();
    
      if(parser.good()) {
        // Da war noch was im Stream
        in.setstate(std::ios_base::failbit);
      }
    
      return in;
    }
    


  • @ Bashar

    also wenn ich int main schreibe, dann bekomm ich diesen fehler

    warning C4508: 'main' : function should return a value; 'void' return type assumed

    bekomm diese warnung öfters und die umgehe ich, wenn ich einfach void main schreibe



  • Hi,

    am Ende der main-Funktion noch ein return 0; setzen. Aber lassen doch mittlerweile viele eh weg, deshalb wundert es mich, das es bei dir nicht klappt.

    gruß Christopher



  • Mohamedyarub schrieb:

    @ Bashar

    also wenn ich int main schreibe, dann bekomm ich diesen fehler

    warning C4508: 'main' : function should return a value; 'void' return type assumed

    bekomm diese warnung öfters und die umgehe ich, wenn ich einfach void main schreibe

    1. Das ist eine Warnung und kein Fehler. Der Unterschied ist dir klar?
    2. void main war schon immer, ist und wird immer falsch sein.
    3. Die Warnung behebst du, indem du das machst, worauf sie dich hinweißt, nämlich einen Wert zurückgeben.

    Wobei ich es seltsam finde, dass der Compiler dafür eine Warnung ausgibt (wo doch die main-Funktion auto. 0 zurückgibt), ihm aber void main keine Warnung wert ist. 😮



  • Die main Funktion gibt beim Erreichen des Scopeende automatisch 0 zurück, insofern wiederspricht die Warnung dem Standard. Welchen Compiler und welche Einstellungen nutzt du?



  • 1. Das ist eine Warnung und kein Fehler. Der Unterschied ist dir klar?

    leider nein

    void main war schon immer, ist und wird immer falsch sein.

    warum übernimmt es das programm? kann das programm mit void main ausführen.

    ich benutze den Microsoft Visual Basic 6.00 standard edition mit den standard einstellungen. hab nichts verändert


  • Mod

    Hmm, ein Basic Compiler für C++, kein Wunder, dass da komische Sachen passieren 😃 .

    Und 6.0? Das ist von wann? 1998? Das ist aus Zeiten, da gab es C++ offiziell noch gar nicht! Warum wunderst du dich da noch, dass der Compiler nicht standardkonform ist?

    Visual Studio (man ist übrigens mittlerweile bei 10, bald kommt 11) ist in der Express-Edition übrigens gratis.



  • Mohamedyarub schrieb:

    1. Das ist eine Warnung und kein Fehler. Der Unterschied ist dir klar?

    leider nein

    Fehler = Wenn du etwas machst, das nicht den Sprachregeln des C++ Standards entspricht, du sozusagen einen Grammatikfehler (Syntaxfehler) begehst.

    Warnung = Der Compiler will dich auf etwas hinweisen. Du hast unter Umständen einen Semantikfehler in deinem Programm. Wenn du z.B. einer int-Variablen einen double-Wert zuweist, macht dich der Compiler darauf aufmerksam, dass es hier zu einem Informationsverlust kommt. Vielleicht ist das von dir so gewollt, da du die Gleitkommazahl abrunden willst. Vielleicht ist das von dir auch nicht so gewollt, du hast dich aus Versehen verschrieben, du wolltest eine double-Variable und keine int-Variable.

    Mohamedyarub schrieb:

    warum übernimmt es das programm? kann das programm mit void main ausführen.
    ich benutze den Microsoft Visual Basic 6.00 standard edition mit den standard einstellungen. hab nichts verändert

    Weil das schon uralt ist. Damals tickten die Compiler noch nicht so standardkonform.



  • pyhax schrieb:

    Gibt es eigentlich in C++11 irgendetwas um dieses Problem zu umgehen?

    Das gabs schon vorher, nämlich getline und stringstream benutzen. Das funktioniert garantiert:

    #include <string>
    #include <iostream>
    #include <sstream>
    
    int main()
    {
    
        std::string command_line;
    
        while(command_line != "quit")
        {
            int x,y,z;
            if(std::getline(std::cin, command_line) && std::istringstream(command_line) >> x >> y >> z)
            {
                std::cout << "x: " << x << "  y: " << y << "  z: " << z << std::endl;
            }
            else
            {
                std::cout << "Bad input: " << command_line << std::endl;
            }
        }
    
    }
    

Anmelden zum Antworten