moneypunct<> facet



  • SeppJ schrieb:

    Bevor ich mir das Gehirn verrenke, um du verstehen, was du da gemacht hast: Weißt du bloß nicht, dass du hättest std::cout << std::put_money(12345) hättest schreiben können oder willst du wirklich wissen, warum das genau so, wie du es gemacht hast, nicht funktioniert? Falls du letzteres wünscht, wäre es gut, wenn du erklärst, wieso du das überhaupt so gemacht hast.

    Das mit std::put_money() ist mir bewusst, ich sah nur so viele Beispiele im Internet, die bei einer selbstdefinierten Facet std::money_put<> anstelle nahmen. Da hab ich das auch so gemacht. Aber put_money() und money_put<> erzielen in diesem Fall das gleiche Ergebnis: 12345.

    Na ich erstelle ein eigenes Facet und überschreibe darin einige Memberfunktionen, die zur Darstellung dienen sollen. In der Hauptfunktion biege ich dann std::cout auf die Locale mit meinem selbstdefinierten Facet um und versuche einen Geldbetrag auszugeben. Aber warum das nicht so klappt, wie ich es mach, weiß ich leider nicht.



  • lokalisiert schrieb:

    Ich habe mir vorgestellt, dass 12'345€ ausgegeben wird, wird aber 12345 ausgegeben.
    Warum?

    weil das so richtig ist.

    Ändere doch mal Zeile 6 nach ' return "\003"; ' und füge vor Zeile 38 noch ein ' std::cout << std::showbase; ' ein.
    Anschließend informiere Dich bitte was ' grouping() ' bedeutet: http://en.cppreference.com/w/cpp/locale/moneypunct/grouping

    Gruß
    Werner



  • Verstehe ich immer noch nicht so recht.
    Ich habe den Code mal auf folgendes umgeändert:

    #include <locale>
    
    struct german_moneypunct : std::moneypunct<char, true>{
        std::string do_curr_symbol() const override{
            return "€";
        }
    
        pattern do_pos_format() const override{
            return pattern{{sign, value, symbol, none}};
        }
    
        char do_thousands_sep() const override{
            return ' ';
        }
    };
    
    #include <iostream>
    #include <iomanip>
    
    int main(){
        std::cout.imbue(std::locale(std::cout.getloc(), new german_moneypunct));
        std::locale loc = std::cout.getloc();
        std::cout << std::showbase << std::put_money(12345);
    
    }
    

    Aber da kommt immer noch '12345' raus, keine Ahnung warum?



  • Bei Deiner Facette ' german_moneypunct ' ist das Flag International gesetzt. Der zweite Parameter im Manipulator put_money ist genau dieses Flag. Der Default-Wert ist hier aber = false .

    Also entweder änderst Du jetzt Zeile 4 nach

    struct german_moneypunct : std::moneypunct<char, false>{ // false ist default und kann auch weg gelassen werden
    

    oder gibst das beim Manipulator in Zeile 26 mit an:

    std::cout << std::showbase << std::put_money( 12345, true );
    

    .. wobei International= true UND 'german_moneypunct' ist doch ein Widerspruch in sich.



  • Tatsache, das klappt.

    Dann hätte ich aber noch zwei Fragen:

    1. Wozu eigentlich das International-Boolean?
    2. Wie kann man mehrere Facets in einer Locale miteinander mischen/verbinden? Einfach durch Mehrfachvererbung?


  • zu 1) weiß ich nicht
    zu 2) was verstehst Du unter mischen/verbinden? Du kannst in eine Locale (im Prinzip) beliebig viele Facetten unterschiedlichen Typs einstellen. Einschließlich neuer User-Defined-Facetten. Siehe dazu auch http://www.angelikalanger.com/Articles/C++Report/UserDefinedFacets/UserDefinedFacets.html



  • Zu 2)

    Ich meine mehrere user-defined Facetten in einer Locale verwenden.
    So z.B. (was nicht geht):

    std::locale loc(std::locale{}, {new german_numpunct, new german_moneypunct});
    

    Wie verwende ich mehrere Facetten innerhalb einer Locale?



  • Ich könnte für jedes Facet ein eigenes Locale erstellen und dann mittels std::locale::combine() zusammenschnipseln.
    Aber irgendwie finde ich, muss es doch eine bessere Lösung dafür geben?



  • lokalisiert schrieb:

    Wie verwende ich mehrere Facetten innerhalb einer Locale?

    Indem Du zwei (oder mehrmals) hintereinander

    std::cout.imbue(std::locale(std::cout.getloc(), new german_moneypunct));
        std::cout.imbue(std::locale(std::cout.getloc(), new mySpezialFacet));
        std::cout.imbue(std::locale(std::cout.getloc(), new numInRoemischenZiffern));
    

    .. den Konstruktor von std::locale aufrufst.

    Bzw. wohl auch so:

    auto loc = std::cout.getloc();
        loc = std::locale( loc, new german_moneypunct );
        loc = std::locale( loc, new mySpezialFacet );
        loc = std::locale( loc, new numInRoemischenZiffern );
        std::cout.imbue( loc );
    

    Wichtig: sie müssen alle über eine eigene std::locale::id verfügen, gleiche Ids werden überschrieben.



  • Ahja, danke.
    Problem gelöst.


Anmelden zum Antworten