Programmieransatz für erstellung einer Menükarte



  • asdfasdf schrieb:

    @Caligulaminus
    hoffentlich hast du das nicht ernst gemeint.

    Wo ist das Problem?



  • Nathan schrieb:

    asdfasdf schrieb:

    @Caligulaminus
    hoffentlich hast du das nicht ernst gemeint.

    Wo ist das Problem?

    der te wollte alle permutationen ausgeben. wieso macht man nicht einfach einen std::vectorstd::string für jede kategorie? in seinem konkreten listing zu bemängeln wäre:
    -alle fleischarten doppelt geschrieben
    -c-strings
    -wer Rind schreiben kann kann auch "Rind" schreiben



  • asdfasdf schrieb:

    Nathan schrieb:

    asdfasdf schrieb:

    @Caligulaminus
    hoffentlich hast du das nicht ernst gemeint.

    Wo ist das Problem?

    der te wollte alle permutationen ausgeben. wieso macht man nicht einfach einen std::vectorstd::string für jede kategorie? in seinem konkreten listing zu bemängeln wäre:
    -alle fleischarten doppelt geschrieben
    -c-strings
    -wer Rind schreiben kann kann auch "Rind" schreiben

    Seine Antwort bezog sich auf die Frage: Wie lass ich mir die Namen eines enums ausgeben. Dass ist die naheliegendste Lösung.
    (etwaige #-Tricks außen vorgelassen)



  • Also leider bin ich immernoch recht verwirrt von dieser Aufgabe, aber bin schon DAnk eureer Hife etwas weiter. Was mich jetzt auch noch mal interessieren würde ist,

    was bedeutet denn das hier?

    char const * const Fleisch[]....
    


  • Um das Menü authentischer zu machen fehlt noch die Option auf Hund



  • Das ist ein Zeiger auf ein char-Array. Also mehr oder weniger ein Dynamisches Array von Strings. An dieser Stelle wären Container besser. Oder gleich schon der Typ std::string



  • So,

    habe jetzt nochmal ein wenig an dem Program gebastelt, die Ausgabe funktioniert soweit schon mal, jetzt habe ich nur das Problem, das zuviel ausgegeben wird.

    main() {
        enum fleisch {Rind, Schwein, Huhn, Ente, Seelachs, Krabben, Maxfleisch};
        enum gemuese {Paprika, Bambus, Sprossen, Bohnen, Zuckerschoten, Pilze, Maxgemuese};
        enum sosse {Suesssauer, Curry, Soja, Erdnuss, Maxsosse};
    
        char const * const Fleisch[] = {"Rind", "Schwein", "Huhn", "Ente", "Seelachs", "Krabben"};
        char const * const Gemuese[] = {"Paprika", "Bambus", "Sprossen", "Bohnen", "Zuckerschoten", "Pilze"};
        char const * const Sosse[] = {"Süßsauer", "Curry", "Soja", "Erdnuss"};
        for (int i=0; i< Maxfleisch;i++){
            cout << Fleisch[i]<< " ";
            for (int j=0; j<Maxgemuese;j++){
                cout << Gemuese[j] << " ";
                for (int k=0 ; k < Maxsosse;k++){
                    cout << Sosse[k] << " ";
                }
            }
            cout << endl;
        }
    

    Die Ausgabe, so wie ich mir sie vorstelle ist:

    Rind Paprika Sußssauer
    Rind Paprika Curry
    ...

    Ich habe mir das ungfähr so gedacht

    for (int i = 0; i < Maxfleisch;) {
            if (k == Erdnuss){
                i++;
            }
            cout << Fleisch[i] << " ";
    

    doch das geht schief.

    jemand eine bessere Idee? (Wahrscheinlich ist jede andere Idee besser 🙂 )



  • Willst du, dass alle möglichen varianten ausgegeben werden oder jeweils ein ausgewählter artikel pro kategorie



  • es sollen alle Varianten ausgegeben werden.



  • Ups.



  • So,

    ich glaube es funktioniert.

    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    int main() {
    
        enum fleisch {
            Rind, Schwein, Huhn, Ente, Seelachs, Krabben, Maxfleisch
        };
    
        enum gemuese {
            Paprika, Bambus, Sprossen, Bohnen, Zuckerschoten, Pilze, Maxgemuese
        };
    
        enum sosse {
            Suesssauer, Curry, Soja, Erdnuss, Maxsosse
        };
    
        char const * const Fleisch[] = {"Rind", "Schwein", "Huhn", "Ente", "Seelachs", "Krabben"};
        char const * const Gemuese[] = {"Paprika", "Bambus", "Sprossen", "Bohnen", "Zuckerschoten", "Pilze"};
        char const * const Sosse[] = {"Süßsauer", "Curry", "Soja", "Erdnuss"};
    
        for (int i = 0; i < Maxfleisch;) {
            //cout << Fleisch[0] << " ";
            for (int j = 0; j < Maxgemuese;) {
                //cout << Gemuese[j] << " ";
                for (int k = 0; k < Maxsosse;) {
                    cout << Fleisch[i]<< " " << Gemuese[j] << " " << Sosse[k] << endl;
    
                    if (k == Erdnuss){
                        j++;
                        cout << endl;
                       if (j== Pilze){
                        i++;
                    }    
                    }
                    k++;
                }
            }
        }
        //cout << Fleisch[0] << " oder " << Fleisch[1] << "?\n";
    }
    


  • .. ich glaube Du hast da noch die Beilage vergessen - oder?

    Übrigens lässt sich die Aufgabe auch mit zwei in einander geschachtelten Schleifen lösen. Unabhängig von der Anzahl der Teile aus denen ein Menü besteht - durch eine zusätzliche Indirektion:

    #include <iostream>
    
    int main() 
    {
        using namespace std;
        // jedes Array muss am Ende einen Nullptr enthalten, um das Array-Ende unabhängig von der Art des Arrays zu erkennen.
        char const * const Fleisch[] = {"Rind", "Schwein", "Huhn", "Ente", "Seelachs", "Krabben", nullptr };
        char const * const Gemuese[] = {"Paprika", "Bambus", "Sprossen", "Bohnen", "Zuckerschoten", "Pilze", nullptr };
        char const * const Sosse[] = {"Süßsauer", "Curry", "Soja", "Erdnuss", nullptr };
        char const * const Beilage[] = {"Reis", "Nudeln", nullptr };
    
        const size_t N = 4; // Menue besteht aus 4 Teilen
        char const* const* basis[N]; // Zeiger auf konstante Zeiger auf konstanten Text
        basis[0] = Fleisch;
        basis[1] = Gemuese;
        basis[2] = Sosse;
        basis[3] = Beilage;
    
        char const* const* gericht[N];
        for( size_t i=0; i<N; ++i )
            gericht[i] = basis[i];
    
        bool weiter;
        do
        {
            // --   Ausgeben des aktuellen Gerichts
            for( size_t i=0; i<N; ++i )
                cout << (i>0? " + ": "") << *gericht[i];
            cout << endl;
    
            // --   Übergang zum nächsten Gericht
            weiter = false;
            for( size_t i=0; i<N; ++i )
            {
                if( *++gericht[i] != nullptr )
                {
                    weiter = true;
                    break;
                }
                gericht[i] = basis[i];
            }
        }
        while( weiter );
    }
    

    Gruß
    Werner



  • Die erinnerung schrieb:

    Oder gleich schon der Typ std::string

    Hab nur den letzten Beitrag gelesen und das ist mir auch gleich aufgefallen. Warum char*? Vor allem von Werner Salomon hätt ich das jetzt nicht unbedingt erwartet.



  • Mechanics schrieb:

    Warum char*?

    Welchen Vorteil sollte std::string hier denn bringen?
    Eine Ente ist eine Ente ist eine Ente. Alles hart codiert.
    char const * const ist hier doch der natürliche Typ - oder übersehe ich etwas?



  • Caligulaminus schrieb:

    Mechanics schrieb:

    Warum char*?

    Welchen Vorteil sollte std::string hier denn bringen?

    1. string ist der typ für zeichenketten, char* ist ein zeiger. (konsistenz)
    2. wenn er die zutaten verketten möchte (ich sage nicht dass er das wirklich will, es geht um den hypothetischen fall), dann kann er das mit std::string ganz intuitiv tun.
    3. mehr typen-sicherheit.
    4. einfacher zu lesen (siehe das array aus c-strings in werner's code, finde ich nicht wirklich einfach zu lesen...).



  • asdfasdf schrieb:

    Caligulaminus schrieb:

    Mechanics schrieb:

    Warum char*?

    Welchen Vorteil sollte std::string hier denn bringen?

    1. string ist der typ für zeichenketten, char* ist ein zeiger. (konsistenz)
    2. wenn er die zutaten verketten möchte (ich sage nicht dass er das wirklich will, es geht um den hypothetischen fall), dann kann er das mit std::string ganz intuitiv tun.
    3. mehr typen-sicherheit.
    4. einfacher zu lesen (siehe das array aus c-strings in werner's code, finde ich nicht wirklich einfach zu lesen...).

    1. char* ist ein Zeiger, std::string ist drei Zeiger.
      2. PaprikaCurry? BambusSchwein?
      3. Könntest Du elaborieren?
      4. Einfacher zu lesen als was?


  • Caligulaminus schrieb:

    asdfasdf schrieb:

    Caligulaminus schrieb:

    Mechanics schrieb:

    Warum char*?

    Welchen Vorteil sollte std::string hier denn bringen?

    1. string ist der typ für zeichenketten, char* ist ein zeiger. (konsistenz)
    2. wenn er die zutaten verketten möchte (ich sage nicht dass er das wirklich will, es geht um den hypothetischen fall), dann kann er das mit std::string ganz intuitiv tun.
    3. mehr typen-sicherheit.
    4. einfacher zu lesen (siehe das array aus c-strings in werner's code, finde ich nicht wirklich einfach zu lesen...).

    1. char* ist ein Zeiger, std::string ist drei Zeiger.
      2. PaprikaCurry? BambusSchwein?
      3. Könntest Du elaborieren?
      4. Einfacher zu lesen als was?

    1. falsch, std::string ist eine klasse, kein zeiger und auch keine drei zeiger. (wie er intern aufgebaut ist ist implementierungsabhängig und irrelevant, da der nutzer dies nie zu gesicht bekommt)
    2. Huhn mit Nudeln? zwischen den zutaten ein wort einzufügen ist ja nicht schwierig.
    3. mit c-strings geht die ganze zeigerarithmetik die mit std::strings nicht geht.
    4. die ganzen nullptr-terminierten arrays von char-zeigern und die arrays von zeigern auf zeiger (weil array-to-pointer-decay) sind für mich unleserlicher als das äquivalent mit std::array und std::string.



  • Ich will mich jetzt hier nicht einmischen, aber std hat nicht umsonst eine (relativ) mächtige string Klasse eingebaut. Sie zu verwenden ist einfach einfacher!



  • std::string = veränderbarer String mit eingebautem Memory-Management(-Overhead).
    const char* = Konstanter String ohne Memory-Management(-Overhead).

    Wer mit Zeichenkettenliteralen arbeitet, sollte daher const char* verwenden. Damit kriegt man sogar Typsicherheit, da const .



  • Wenn man die Operationen von std::string nicht braucht, braucht man auch std::string nicht. Das std::string der natürliche Typ für Strings ist, ist auch offensichtlich falsch, dann wären String-Literale vom Typ std::string. Sie sind aber konstante char-Arrays.


Anmelden zum Antworten