In Datei schreiben



  • Vielen Dank für die sehr ausführlichen Antworten! Sind sehr gute Tipps und Informationen dabei, die mir weiterhelfen.

    Zu 1: Ich wusste gar nicht, das diese nicht kompatible sind. Werde beim nächsten mal solche Dinge löschen.

    zu 3: Kannst du mir vllt mal zeigen, wie du diese Schleife aufbauen würdest? In jedem Buch, oder Tutorial habe ich Konsolenmenüs immer so aufgebaut vorgefunden. Deswegen habe ich mir das auch so eingeprägt. Sollte es bessere oder effizientere Wege geben, wüsste ich sie sehr gerne 😃

    zu 4: Ok, das die Konsole für Nutzereingaben nicht richtig geeignet ist hätte ich jetzt auch nicht gedacht. Bis jetzt kenne ich nur die Arbeit mit der Konsole. Allerdings dient auch alles nur der Vertiefung des gelesenen und da ist die Konsole der einfachste Weg denke ich.

    zu 5: Visual Studio Express 2013
    1 Warnung c4003: Nicht genügend übergebene Parameter für das Makro max
    Fehler 2 error C2589: '(': Ungültiges Token auf der rechten Seite von '::' f:\cpp uebungen\files\files\quelle.cpp 79 1 Files
    Fehler 3 error C2143: Syntaxfehler: Es fehlt ')' vor '::' f:\cpp uebungen\files\files\quelle.cpp 79 1 Files
    Fehler 4 error C2059: Syntaxfehler: ')' f:\cpp uebungen\files\files\quelle.cpp 79 1 Files
    5 IntelliSense: Es wurde ein Bezeichner erwartet. f:\CPP Uebungen\Files\Files\Quelle.cpp 79 42 Files

    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    Hab auch versucht anstelle von streamsize int usw einzusetzen, dies hatte aber keine Auswirkung.

    zu 6: Was wäre den anstelle von numeric_limits gutes Design, bzw welche alternativen hat man? 😃
    LG



  • tomy86 schrieb:

    zu 3: Kannst du mir vllt mal zeigen, wie du diese Schleife aufbauen würdest? In jedem Buch, oder Tutorial habe ich Konsolenmenüs immer so aufgebaut vorgefunden. Deswegen habe ich mir das auch so eingeprägt. Sollte es bessere oder effizientere Wege geben, wüsste ich sie sehr gerne

    Für ein Konsolenmenü hab ich irgendwann mal eine einfach zu verwendende Klasse geschrieben. Du findest sie hier:
    https://www.c-plusplus.net/forum/303169

    Edit: Klappt nur unter Windows-Konsole



  • tomy86 schrieb:

    zu 5: Visual Studio Express 2013
    1 Warnung c4003: Nicht genügend übergebene Parameter für das Makro max
    Fehler 2 error C2589: '(': Ungültiges Token auf der rechten Seite von '::' f:\cpp uebungen\files\files\quelle.cpp 79 1 Files
    Fehler 3 error C2143: Syntaxfehler: Es fehlt ')' vor '::' f:\cpp uebungen\files\files\quelle.cpp 79 1 Files
    Fehler 4 error C2059: Syntaxfehler: ')' f:\cpp uebungen\files\files\quelle.cpp 79 1 Files
    5 IntelliSense: Es wurde ein Bezeichner erwartet. f:\CPP Uebungen\Files\Files\Quelle.cpp 79 42 Files

    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    Hab auch versucht anstelle von streamsize int usw einzusetzen, dies hatte aber

    In windows.h wird ein Makro max definiert, das gerne zu solchen Fehlern führt. Ein Define NOMINMAX (am Besten auf der Kommandozeile) schaltet es ab.



  • Belli schrieb:

    tomy86 schrieb:

    zu 3: Kannst du mir vllt mal zeigen, wie du diese Schleife aufbauen würdest? In jedem Buch, oder Tutorial habe ich Konsolenmenüs immer so aufgebaut vorgefunden. Deswegen habe ich mir das auch so eingeprägt. Sollte es bessere oder effizientere Wege geben, wüsste ich sie sehr gerne

    Für ein Konsolenmenü hab ich irgendwann mal eine einfach zu verwendende Klasse geschrieben. Du findest sie hier:
    https://www.c-plusplus.net/forum/303169

    Edit: Klappt nur unter Windows-Konsole

    Danke für den guten Tipp. Werde das Studieren, wenn ich mich mehr mit der OOP auseinandergesetzt habe. Ist im Moment aber noch n bissl kompliziert für mich 😉

    manni66 schrieb:

    tomy86 schrieb:

    zu 5: Visual Studio Express 2013
    1 Warnung c4003: Nicht genügend übergebene Parameter für das Makro max
    Fehler 2 error C2589: '(': Ungültiges Token auf der rechten Seite von '::' f:\cpp uebungen\files\files\quelle.cpp 79 1 Files
    Fehler 3 error C2143: Syntaxfehler: Es fehlt ')' vor '::' f:\cpp uebungen\files\files\quelle.cpp 79 1 Files
    Fehler 4 error C2059: Syntaxfehler: ')' f:\cpp uebungen\files\files\quelle.cpp 79 1 Files
    5 IntelliSense: Es wurde ein Bezeichner erwartet. f:\CPP Uebungen\Files\Files\Quelle.cpp 79 42 Files

    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    Hab auch versucht anstelle von streamsize int usw einzusetzen, dies hatte aber

    In windows.h wird ein Makro max definiert, das gerne zu solchen Fehlern führt. Ein Define NOMINMAX (am Besten auf der Kommandozeile) schaltet es ab.

    Es tut mir leid, aber ich weiß leider nicht was du genau meinst? Wie soll ich das #define NOMINMAX definieren, also was soll da fürn Wert usw rein?



  • Die Klasse kannst Du sehr einfach verwenden. In dem Posting ist ja auch ein kurzes Testprogramm!

    Du kannst die Makros min/max aus windows.h deaktivieren, indem Du VOR

    #include <windows.h>
    

    einfügst:

    #define NOMINMAX
    

    Alternativ sollte es auch funktionieren im Programm explizit die Standardbibliothek zu qualifizieren, indem man

    std::max(...
    

    anstelle von

    max(...
    

    verwendet.



  • tomy86 schrieb:

    Wie soll ich das #define NOMINMAX definieren, also was soll da fürn Wert usw rein?

    Da kommt kein Wert rein. Entweder du schreibst es einfach so

    #define NOMINMAX
    

    in die Datei oder du rufst den Compiler mit -DNOMINMAX auf.



  • Ich danke euch beiden vielmals. Jetzt läuft alles soweit erstmal.
    @Belli
    Ja, die Verwendung scheint auf dem ersten Blick recht simpel zu sein. Ich meine mit Studieren auch eher die genaue Funktionsweise 🙂
    Ich möchte ja lernen und nicht nur kopieren 😉
    Aber mein Buch ist noch nicht soweit, das die OOP zum tragen kommt. Und ich möchte mich erstmal an den Buchverlauf halten 🙂

    Aber ich hätte da doch noch mal eine Frage. Und zwar warum schaltet NOMINMAX die min, bzw max Methoden aus? Und warum nur in der windows.h und nicht ganz?



  • Noch eine Alternative zu NOMINMAX :
    `#include <windows.h>

    //...

    (std::numeric_limits<streamsize>::max)()`

    Die Klammern um std::numeric_limits<streamsize>::max verhindern dabei dass max als Function-Style Makro erkannt und expandiert wird.
    Ist nicht schön, aber in manchen Projekten wo es auf Kompatibilität ankommt eine gute Lösung.
    Weil es auch dann funktioniert, wenn windows.h schon von wo anders aus, ohne Definition von NOMINMAX inkludiert wurde.



  • tomy86 schrieb:

    Aber ich hätte da doch noch mal eine Frage. Und zwar warum schaltet NOMINMAX die min, bzw max Methoden aus? Und warum nur in der windows.h und nicht ganz?

    Das unangenehme a windows.h ist, dass es viel macros enthält (also #define) und min()/max() dort eben als macro definiert wird. NOMINMAX verhindert das



  • tomy86 schrieb:

    Und zwar warum schaltet NOMINMAX die min, bzw max Methoden aus? Und warum nur in der windows.h und nicht ganz?

    Huch?
    NOMINMAX sorgt dafür dass windows.h keine MAKROS mit den Namen min und max definiert.

    Im Prinzip steht in windows.h (sinngemäss)

    #if !defined(NOMINMAX) && !defined(min)
    #define min(a, b) ...
    #endif
    #if !defined(NOMINMAX) && !defined(max)
    #define max(a, b) ...
    #endif
    


  • coder777 schrieb:

    tomy86 schrieb:

    Aber ich hätte da doch noch mal eine Frage. Und zwar warum schaltet NOMINMAX die min, bzw max Methoden aus? Und warum nur in der windows.h und nicht ganz?

    Das unangenehme a windows.h ist, dass es viel macros enthält (also #define) und min()/max() dort eben als macro definiert wird. NOMINMAX verhindert das

    hustbaer schrieb:

    tomy86 schrieb:

    Und zwar warum schaltet NOMINMAX die min, bzw max Methoden aus? Und warum nur in der windows.h und nicht ganz?

    Huch?
    NOMINMAX sorgt dafür dass windows.h keine MAKROS mit den Namen min und max definiert.

    Im Prinzip steht in windows.h (sinngemäss)

    #if !defined(NOMINMAX) && !defined(min)
    #define min(a, b) ...
    #endif
    #if !defined(NOMINMAX) && !defined(max)
    #define max(a, b) ...
    #endif
    

    Ah ok, jetzt hab ich das Verstanden, ich danke für die Erklärungen 😃

    hustbaer schrieb:

    Noch eine Alternative zu NOMINMAX :
    `#include <windows.h>

    //...

    (std::numeric_limits<streamsize>::max)()`

    Die Klammern um std::numeric_limits<streamsize>::max verhindern dabei dass max als Function-Style Makro erkannt und expandiert wird.
    Ist nicht schön, aber in manchen Projekten wo es auf Kompatibilität ankommt eine gute Lösung.
    Weil es auch dann funktioniert, wenn windows.h schon von wo anders aus, ohne Definition von NOMINMAX inkludiert wurde.

    Sollte man nicht eh nur einmal windows,h, iostream usw inkludieren?
    Beim Visual Studio gibts ja die Möglichkeit mit vorkompilierten Headern ein Projekt zu erstellen. Da gibts dann eine Datei, in der man alle häufig benötigten Dateien inkludiert. Also z.B. iostream, windows.h usw. Oder hab ich auch da was falsch Verstanden?



  • @tomy86
    Angenommen...
    Ich entwickle eine Library "Foo" in der viel inline implementiert ist.
    Ich brauche in dieser Library std::numeric_limits<streamsize>::max() .
    Ich schreibe also

    // Foo.hpp
    #define NOMINMAX
    #include <windows.h> // Weil ich irgendwo WinAPI Funktionen brauche
    
    // ...
    
    inline void Bar()
    {
        // ...
        auto const m = std::numeric_limits<streamsize>::max();
        // ...
    }
    

    Und jemand der meine Library verwendet schreibt

    #include <windows.h>
    #include <Header File einer anderen Library welches dummerweise die min und max Macros aus windows.h braucht.h>
    #include <Foo.hpp>
    

    Dann gibt's ein Problem, und zwar weil zu dem Zeitpunkt wo windows.h das erste mal inkludiert wurde NOMINMAX nicht definiert war.
    Also wurden die min und max Makros definiert.
    Hässlicher Fix:

    #include <windows.h>
    #include <Header File einer anderen Library welches dummerweise die min und max Macros aus windows.h braucht.h>
    #undef min
    #undef max
    #include <Foo.hpp>
    

    Und eine Möglichkeit solchen Problemen aus dem Weg zu gehen, so dass der Anwender meiner Library "Foo" diesen hässlichen Workaround nicht machen muss, ist eben (std::numeric_limits<streamsize>::max)() zu schreiben.



  • Es gibt da noch eine Möglichkeit.

    //kann man von Boost nehmen oder selber definieren
    #define BOOST_PREVENT_MACRO_SUBSTITUTION
    
    std::numeric_limits<std::streamsize>::max BOOST_PREVENT_MACRO_SUBSTITUTION ()
    

    Hat den Vorteil, dass niemand den Workaround versehentlich entfernt (bei Copy-Paste zum Beispiel). Bei (std::numeric_limits<streamsize>::max) ist nicht erkennbar, warum da redundante Klammern stehen.
    Wer sich aber über BOOST_PREVENT_MACRO_SUBSTITUTION wundert, kann das Googlen.



  • Ah, ok. Und die Klammern haben ihre Wirkung, da das max zu numeric_limits gehört und somit zusammen abgearbeitet wird? Also zb so wie bei (3+3)*3? Wobei hier 3+3 das numeric_limit::max entspricht und *3 das max Makro aus windows.h?



  • string dateiname()
    {
    string name;
    cout << "Bitte gib den Dateinamen an: ";
    cin >> name;
    return name.append(".txt");
    }

    geht das auch, wenn ich "test.txt" eingebe?



  • Die Klammern haben hier bloss den Sinn dass der Präprozessor es nicht mehr als Kandidat für ein Function-Style-Makro durchgehen lässt.

    Wobei ich die von TyRoXx vorgeschlagene Variante eigentlich besser finde. Aus den von ihm genannten Gründen.



  • hardware schrieb:

    string dateiname()
    {
    string name;
    cout << "Bitte gib den Dateinamen an: ";
    cin >> name;
    return name.append(".txt");
    }

    geht das auch, wenn ich "test.txt" eingebe?

    Ja auch das geht. Man könnte sogar test.exe eingeben, aber da ans Ende das .txt angehangen wird, wird die Datei in jedem Fall auch als Textdatei gehandhabt.

    hustbaer schrieb:

    Die Klammern haben hier bloss den Sinn dass der Präprozessor es nicht mehr als Kandidat für ein Function-Style-Makro durchgehen lässt.

    Wobei ich die von TyRoXx vorgeschlagene Variante eigentlich besser finde. Aus den von ihm genannten Gründen.

    Die Frage diente in erster Linie dem Verständnis dafür, wie die Klammern arbeiten. Und ob das immer so ist, oder nur in diesem speziellen Fall.



  • @tomy86
    Also was die Klammern bewirken muss man sich 2x angucken.
    Erstmal was den Präprozessor betrifft und dann nochmal was die C++ Grammatik angeht.

    Was den Präprozessor angeht hab ich ja schon geschrieben. Dass der PP hier das "max" in den Klammern nicht mehr als Name eines Function-Style Makros in Betracht zieht ist ja der erwünschte Effekt. Die genauen Grammatikregeln müsstest du ggf. selbst nachgucken.

    Danach kommt die "eigentliche" C++ Übersetzung.
    Wenn ich das richtig verstehe (ich hoffe ich erzähle jetzt keinen Unsinn)...

    Ein Funktionsaufruf ist in der C++ Grammatik eine postfix-expression
    und zwar in der Form
    postfix-expression ( expression-list opt )
    Der erste Teil "benennt" dabei die Funktion, der Teil in der Klammer ist die optionale Parameterliste.

    std::numeric_limits<streamsize>::max als solches ist eine qualified-id, und damit automatisch auch eine postfix-expression.
    Passt also oben als erster Teil des Funktionsaufrufs (der Teil der die Funktion "benennt").

    (std::numeric_limits<streamsize>::max) würde an der Stelle dann als primary-expression geparsed,
    und zwar in der Form
    ( expression ) .
    Da eine primary-expression auch eine postfix-expression ist, funktioniert das auch als 1. Teil des Funktionsaufrufs.

    D.h. beides geht schonmal als valide C++ Grammatik durch.
    Das bedeutet jetzt nicht automatisch dass auch der Effekt beider Expressions gleichbedeutend ist, aber in diesem Fall ist er es halt 🙂
    (Heisst: manchmal ist (x) an einer Stelle wo man auch nur x schreiben könnte eben nicht gleichbedeutend mit nur x .)



  • @hustbaer
    Vielen Dank, für die ausführliche Erklärung 😃


Anmelden zum Antworten