Kurze Frage , Kurze Antwort



  • Kann ich eine Do While schleife in einer Do while schleife haben?

    Beispiel:

    do 
    {
    <restlicher code>
    do
    {
    <mehr restlicher code>
    }while (X != 1)
    }while (y != 1)
    


  • Wieso nicht. Probiers doch einfach aus.


  • Mod

    Skym0sh0 schrieb:

    SeppJ schrieb:

    Skym0sh0 schrieb:

    Zur Not machst dus wie die Standardbibliothek und machst halt Templates aus den Parametern:

    Das sollte nicht der Notfall, sondern der Normalfall sein. Ich bin gerade nur etwas verwirrt, ob der TE einen legitimen Grund hat, das nicht so zu machen, oder ob er das einfach nur nicht kennt.

    Sollte es echt der Normalfall sein? 😕
    Ich mein, man müsste die Funktion ja dann allgemein halten.

    Und eigentlich fehlen dann noch type_traits und sowas...

    Andersrum: Wenn man eine allgemeine Funktion wünscht (oder die Funktion sowieso schon allgemein ist*), dann ist dies der normale Weg.

    *: Ich weiß nicht, wie es euch geht, aber ich habe andauernd den Fall, dass ich bei einer Funktion Eigenschaften wie "eigentlich ist es ganz egal, welche Art von Daten sie verarbeitet, Hauptsache irgendwie iterierbar" oder ähnliches bemerke+. Dann kann und werde ich diesen Umstand auch nutzen. Vielleicht programmiere ich auch unterbewusst abstrakter als die meisten anderen Leute.
    +: Normalerweise nicht im Nachhinein, sondern schon im Voraus, wenn ich mir die Aufgabe der Funktion überlege und wie sie dies ungefähr umsetzt. Aber es ist auch schon vorgekommen, dass ich die Abstraktion erst im Nachhinein bemerkt habe.



  • Again, kurze Frage zum "zeichen für zeichen" einlesen :

    char buffer[20]
    std::ifstream datei("test.txt", std::ios_base::in);
    
    for (int i = 0; i < ...){
    
       buffer[i] = datei.get();
         //oder
       datei.get(buffer[i]);
    }
    

    Egal, oder ist eine Verison vorzuziehen?



  • Nachtrag:

    oder wenn ich die Länge des Textes weiß, Variante 3:

    char *cp = new char [len] ;
    
     datei.getline(cp, len);
    


  • int_type get();
    
    1. Reads one character and returns it if available. Otherwise, returns Traits::eof() and sets failbit and eofbit.
    basic_istream& get(char_type& ch);
    
    1. Reads one character and stores it to ch if available. Otherwise, leaves ch unmodified and sets failbit and eofbit. Note that this function is not overloaded on the types signed char and unsigned char, unlike the formatted character input operator>>.
    1. liefert dir im Fehlerfall eof zurück, 2) ändert im Fehlerfall buffer[i] nicht.
      Ich würde 2) verwenden, weil man dann einfach schön den Stream prüfen kann.
    if (!datei.get(buffer[i]))
      error();
    


  • cpp_beg schrieb:

    Nachtrag:

    oder wenn ich die Länge des Textes weiß, Variante 3:

    char *cp = new char [len] ;
     
     datei.getline(cp, len);
    

    Vorausgesetzt du verwendest ordentliches RAII und kein new.



  • Ich check das mit dem RAII nicht ganz. Hab mir den Wikipedia Artikel schon durchgelesen, aber wie wäre das in oben geannten Bspl. angewandt?



  • beg_offl schrieb:

    Ich check das mit dem RAII nicht ganz. Hab mir den Wikipedia Artikel schon durchgelesen, aber wie wäre das in oben geannten Bspl. angewandt?

    Zum Beispiel mit dem Nutzen von std::vector oder std::unique_ptr<char[]>.



  • Nathan schrieb:

    int_type get();
    
    1. Reads one character and returns it if available. Otherwise, returns Traits::eof() and sets failbit and eofbit.
    basic_istream& get(char_type& ch);
    
    1. Reads one character and stores it to ch if available. Otherwise, leaves ch unmodified and sets failbit and eofbit. Note that this function is not overloaded on the types signed char and unsigned char, unlike the formatted character input operator>>.
    1. liefert dir im Fehlerfall eof zurück, 2) ändert im Fehlerfall buffer[i] nicht.
      Ich würde 2) verwenden, weil man dann einfach schön den Stream prüfen kann.
    if (!datei.get(buffer[i]))
      error();
    

    Würde dann folgendes Reichen um eine Datei Zeichen für Zeichen einzulesen? Das ist Fehlerprüfungstechnisch etwas dünn oder??

    std::fstream orig("orig.txt", std::ios_base::in);
    
    char c;
    
    while( orig.get(c) ){
    
    	std::cout << c;
    }
    


  • Solte ich EOF evtl. mit einbauen?

    while( orig.get(c) ){
    
        if ( c != EOF) {    //???
           std::cout << c;
        } else.... 
    }
    


  • beg_offl schrieb:

    Solte ich EOF evtl. mit einbauen?

    Nein, c kann nie EOF sein.
    Die erste Version ist absolut richtig und deckt alle Fehler ab.



  • Ähm ja, c sollte dann natürlich ein INT sein.
    Also brauch ich gar keine Abfragen mehr auf EOF machen?



  • Noch ne Frage, wie werte ich eine Schreibaktion mit write aus?

    datei.write(reinterpret_cast <char*>(&myInt), sizeof(myInt); 
    
    ??? if !(????);
    

    Ich werd jetzt aus der Refernz nicht schlau, da steht bei Return Value "*this" . Ok ich weiß das "this" ein Zeiger aufs Objekt ist oder so (Ich bin noch nicht soweit mit Lernen), aber ledier ist kein Bspl. dabei wie ich das auswerten könnte....


  • Mod

    beg_ok schrieb:

    Also brauch ich gar keine Abfragen mehr auf EOF machen?

    Nathan schrieb:

    Die erste Version ist absolut richtig und deckt alle Fehler ab.

    Typische Leseschleifen in C++ gehen so:
    Leseoperationen auf Streams geben (bis auf ganz wenige Ausnahmen) immer den Stream selbst als return-Wert zurück. Dadurch kann man einerseits mehrere Leseoperationen nacheinander schalten:

    cin >> wert1 >> wert2 >> wert3;
    

    Da passiert folgendes:
    cin >> wert1 wird durchgeführt. Der Rückgabewert davon ist wieder cin (oder genauer: Eine Referenz darauf), also bleibt cin >> wert2 >> wert3; übrig. Dann das ganze nochmal und es bleibt cin >> wert3; übrig. Und dann das ganze nochmal, und der Rückgabewert des gesamten Ausdrucks ist also am Ende nur cin . Wozu ist das noch gut? Nun, die Streams kann man auch zu Wahrheitswerten konvertieren (also zu Werten, wie sie von if, while, for, usw. verarbeitet werden). Dabei gilt: Ist irgendein Fehlerflag des Streams gesetzt (unter anderem kann das EOF sein, aber auch alle anderen Fehler werden so markiert), dann kommt false raus, ansonsten - das heißt, wenn der Stream einsatzbereit ist - kommt true raus. Man kann so also ganz einfach prüfen, ob eine Leseaktion erfolgreich war:

    if (cin >> wert1 >> wert2 >> wert3)
      // Lesen war erfolgreich
    else
      // Es gab einen Fehler
    

    (Man denke da dran, dass, wenn die erste Aktion, cin >> wert1 , bereits fehlschlug, alle weiteren Aktionen auf dem Stream automatisch fehlschlagen, bis die Fehlerflags ge- clear -ed wurden. Es passiert also nichts komisches mit wert2 oder wert3.)

    Üblicherweise hat man ja auch mehrere Leseaktionen in einer Schleife, da geht das dann genau so:

    while (cin >> wert)
    {
      verarbeite(wert);
    }
    

    Da werden so lange Werte gelesen und verarbeitet, bis ein Fehler auftritt. Das kann beispielsweise das Erreichen des Dateiendes sein. Und ganz wichtig: Im Fehlerfall wird der Schleifenkörper gar nicht mehr ausgeführt, es werden also nur korrekt gelesene Werte verarbeitet. Man sieht oft in schlechten Lehrbüchern:

    while(!cin.eof())
    {
      cin >> wert;
      verarbeite(wert);
    }
    

    Das ist, wie du nun hoffentlich erkennst, doppelt falsch. Erstens fängt es nicht alle Fehler ab, weil nur auf eof geprüft wird (im Falle anderer Fehler hätte man also eine Endlosschleife) und zweitens wird selbst nach Auftreten von EOF noch einmal ein wert verarbeitet, obwohl er gar nicht korrekt gelesen wurde! Merke: Der Fehlerzustand tritt erst ein, dann wenn eine Leseaktion fehlschlägt, nicht wenn die nächste Leseaktion fehlschlagen könnte. Bloß weil die letzte Leseaktion den Lesezeiger direkt vor dem Ende einer Datei positioniert hat, ist das noch so lange nicht EOF, bis nicht versucht wurde, über das Ende der Datei zu lesen. Der Computer kann schließlich nicht wissen, ob jemals eine solche Aktion stattfinden wird und vorschnell Alarm schlagen.

    Diese Dinge sollten in jedem guten Anfängerbuch erklärt werden (Minus der Erklärung, was man nicht tun sollte). Es ist daher erschreckend, dass du das nicht weißt und lässt mich an der Qualität deines Lehrstoffs zweifeln. Ganz schlimm wäre es, wenn dort sogar die falsche Variante demonstriert wird. Dann sollte das Buch direkt in den Mülleimer wandern.

    Noch zwei kleine Anmerkungen:
    -Statt while werden oft auch andere Schleifentypen, zum Beispiel for benutzt. while ist nur ein Beispiel.
    -Der kleine Aufsatz über Fehlerzustände und wann sie eintreten (nach dem Fehler!), gilt so in allen Sprachen, die von C abstammen (C++, Java, viele mehr) und in vielen anderen Sprachen. Manchmal trifft man Leute, die sagen, dass es in C anders wäre. Das stimmt nicht! Das ist fast nur bei einigen altertümlichen Lehrsprachen der Fall, wie Pascal oder frühen BASIC-Dialekten. Die Leute, die das verbreiten, haben also das letzte Mal ihre Programmierkenntnisse in den 1980ern aufgefrischt (oder haben von Leuten gelernt, für die das gilt).

    P.S.: Das alles gilt natürlich ebenso für Schreibaktionen, wenn man tatsächlich mal prüfen möchte, ob diese erfolgreich waren.



  • Danke, gute Erklärung

    Zum Buchstoff : Ich arbe mit dem C++ Primer, da habe ich über EOF noch nicht wirklich was gefunden, kommt erst ziemlich weit hinten, aber ich bastle mal wieder davor schon etwas rum.
    Ausserdem hab ich noch The C++ Programming Language von Bjarne S. aber die deutsche Version. (Finde das Buch nicht so den Hit. , aber es "ging billig her" ).

    Auf jeden Fall hab ich gestern noch das C++ Kochbuch erhalten und siehe an :

    void loadCSV(istream& in, vector<vector<string>*>& data) {
    vector<string>* p = NULL;
    string tmp;
    while (!in.eof( )) {
    getline(in, tmp, '\n'); // Hole die nächste Zeile
    p = new vector<string>( );
    

    => ist jetzt nur ein freigewähltes Beispiel, aber die while(! .eof) Abfrage kommt da relativ häufig vor.



  • cpp_beginner schrieb:

    => ist jetzt nur ein freigewähltes Beispiel, aber die while(! .eof) Abfrage kommt da relativ häufig vor.

    Das ist ein schlechtes Buch, und nicht nur wegen dem eof.


  • Mod

    Daran siehst, du dass der Primer und der Stroustrup was taugen und das C++-Kochbuch in den Müll gehört*. Das sieht man noch an mehr Punkten aus dem Beispiel: Zeiger auf vector? Ungekapseltes new? 3 dicke Fehler auf 6 Zeilen!

    *: Das ist kein dummer Spruch, das ist wörtlich gemeint und mein voller Ernst. Meinetwegen auch als Türstopper oder Briefbeschwerer. Aber es gehört nicht gelesen und auch nicht weiterverkauft, außer vielleicht an deine Feinde.



  • Ungekapseltes new?

    Wie meinst du das?


  • Mod

    beg__ schrieb:

    Ungekapseltes new?

    Wie meinst du das?

    Lies einfach ein gutes Buch. Ich jedenfalls habe keine Lust, dir jeden Mist, den du irgendwo aufgeschnappt hast, einzeln auszutreiben. Weißt du was Kapselung ist? Falls nein -> Grundlagen. Weißt du was new ist? Falls nein -> Gut so 😉 . Falls du weißt was beides ist, kannst du dann erraten, was wohl ein ungekapseltes new ist?


Anmelden zum Antworten