C - Konsolen Menü

  • Hallo Leute,

    ich habe im Studium einfach mal ein einfach anzuwendenes Menü für die Konsole in C geschrieben.
    Und ist komplett dynamisch.

    [Blockierte Grafik: http://lvps178-77-72-233.dedicated.hosteurope.de/~ron/temp/Unbenannt.png]

    Das Menü ist einfach anzuwenden:

    showMenu(
    &aufgabe_1, "Aufgabe 1: Doller<->Euro Umrechner",
    &aufgabe_2, "Aufgabe 2: printTable",
    &aufgabe_3, "Aufgabe 3: Datum Kontrolle",
    &zusatzAufgabe_TageBisWeihnachten, "Zusatzaufgabe Tage bis Weihnachten",
    &zusatzAufgabe_DatumsDifferenz, "Zusatzaufgabe Tages Differenz",
    &zusatzAufgabe_Ostersonntag, "Zusatzaufgabe Ostersonntag",
    &zusatzAufgabe_TageBisWeihnachtenKontrolle,"Zusatzaufgabe Tage bis Weihnachten Kontrolle",
    &zusatzAufgabe_DatumsDifferenzKontrolle, "Zusatzaufgabe Tages Differenz Kontrolle",
    &zusatzAufgabe_OstersonntagKontrolle, "Zusatzaufgabe Ostersonntag Kontrolle",
    NULL
    );


    Also die Funktionen wie bsp.: aufgabe_1 ist eine: void aufgabe_1(void)
    void showMenu(void(*function)(void), ...)


    Also immer eine Funktion dann der Text. Das beliebig oft in Kombination.
    Ich füge nur die Quelldatei ein, den Header kann man sich ja selbst schreiben. Wer nicht weiß wie:
    Prototypen
    http://de.wikibooks.org/wiki/C-Programmierung:_Funktionen


    Quelltext der Funktion

    Spoiler anzeigen
    [autoit]

    #include "Hilfen.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #define HILFEN_AUSGABE
    #define HILFEN_EXITMENU

    [/autoit] [autoit][/autoit] [autoit]

    void readDouble(double *dValue,char *szText)
    {
    int bIsEingabeOk = 1; //Als boolean behandeln
    do
    {
    if (bIsEingabeOk == 0)
    {
    printf_s("\nFalsches Format bitte nur Zahlen und Punkt verwenden. (x.xx)\n");
    fflush(stdin); //Eingabe Puffer l�schen.
    }
    printf_s("\n%s ", szText);
    bIsEingabeOk = scanf_s("%lf", dValue);
    } while (bIsEingabeOk == 0);
    }
    void readInt(int *nValue, char *szText)
    {
    int bIsEingabeOk = 1; //Als boolean behandeln
    do
    {
    if (bIsEingabeOk == 0)
    {
    printf_s("\nFalsches Format bitte nur Zahlen verwenden. (x)\n");
    fflush(stdin); //Eingabe Puffer l�schen.
    }
    printf_s("\n%s ", szText);
    bIsEingabeOk = scanf_s("%i", nValue);
    } while (bIsEingabeOk == 0);
    }

    [/autoit] [autoit][/autoit] [autoit]

    void showMenu(void(*function)(void), ...)
    {
    /*Ausgabe*/ //Nicht Zwingend notwendig ist der Rahmen
    /*Einfach #define HILFEN_AUSGABE Auskommentieren um Rahmen zu entfernen*/
    /*Einfach #define HILFEN_EXITMENU Auskommentieren um das Beenden des Men�s zu deaktivieren*/

    [/autoit] [autoit][/autoit] [autoit]

    va_list argptr;
    char* strArgs;
    int nZaehler = 0;
    int nEingabe = 0;
    int nPointer = 0;
    int nMenuSize = 1;
    int nClearScreen = 0;
    int nExitMenue = 0;
    int nExitProgramm = 0;
    void(*newFunction)(void);
    do
    {
    nZaehler = 1;
    nEingabe = 0;
    nPointer = 2;
    nMenuSize = 1;
    nClearScreen = 0;
    nExitMenue = 0;
    nExitProgramm = 0;
    va_start(argptr, function);
    strArgs = va_arg(argptr, char*);
    #ifdef HILFEN_AUSGABE
    /*Ausgabe*/printf_s("\n%c", 218);
    /*Ausgabe*/for (nMenuSize = 1; nMenuSize <= 60; nMenuSize++) printf_s("%c", 196);
    /*Ausgabe*/printf_s("%c\n", 191);
    /*Ausgabe*/printf_s("%c", 195);
    /*Ausgabe*/for (nMenuSize = 1; nMenuSize <= 60; nMenuSize++) printf_s("%c", 196);
    /*Ausgabe*/printf_s("%c\n", 180);
    /*Ausgabe*/printf_s("%c%27cMen\x81%29c%c\n", 179, 32, 32, 179);
    /*Ausgabe*/printf_s("%c", 195);
    /*Ausgabe*/for (nMenuSize = 1; nMenuSize <= 60; nMenuSize++) printf_s("%c", 196);
    /*Ausgabe*/printf_s("%c\n", 180);
    #endif
    while (strArgs != NULL)
    {
    #ifdef HILFEN_AUSGABE
    printf_s("%c %3i - %-53s%c\n", 179, nZaehler++, strArgs, 179);
    #else
    printf_s("%3i - %-53s\n",nZaehler++, strArgs);
    #endif
    newFunction = va_arg(argptr, void*);
    if (newFunction == NULL)
    break;
    strArgs = va_arg(argptr, char*);
    };
    va_end(argptr);
    #ifdef HILFEN_AUSGABE
    /*Ausgabe*/printf_s("%c", 195);
    /*Ausgabe*/for (nMenuSize = 1; nMenuSize <= 60; nMenuSize++) printf_s("%c", 196);
    /*Ausgabe*/printf_s("%c\n", 180);
    #endif
    nClearScreen = nZaehler;
    #ifdef HILFEN_AUSGABE
    printf_s("%c %3i - %-53s%c\n", 179, nClearScreen, "Bildschirm leeren", 179);
    #else
    printf_s("%3i - %-53s\n", nClearScreen, "Bildschirm leeren");
    #endif
    #ifdef HILFEN_EXITMENU
    nExitMenue = nClearScreen + 1;
    #ifdef HILFEN_AUSGABE
    printf_s("%c %3i - %-53s%c\n", 179, nExitMenue, "Men\x81 beenden", 179);
    #else
    printf_s("%3i - %-53s\n", nExitMenue, "Men\x81 beenden");
    #endif
    nExitProgramm = nExitMenue + 1;
    #else
    nExitProgramm = nClearScreen + 1;
    #endif


    #ifdef HILFEN_AUSGABE
    printf_s("%c %3i - %-53s%c\n", 179, nExitProgramm, "Programm beenden", 179);
    #else
    printf_s("%3i - %-53s\n", nExitProgramm, "Programm beenden");
    #endif
    #ifdef HILFEN_AUSGABE
    /*Ausgabe*/printf_s("%c", 195);
    /*Ausgabe*/for (nMenuSize = 1; nMenuSize <= 60; nMenuSize++) printf_s("%c", 196);
    /*Ausgabe*/printf_s("%c\n", 180);
    /*Ausgabe*/printf_s("%c", 192);
    /*Ausgabe*/for (nMenuSize = 1; nMenuSize <= 60; nMenuSize++) printf_s("%c", 196);
    /*Ausgabe*/printf_s("%c\n", 217);
    #endif
    readInt(&nEingabe, "Ihre Auswahl:");

    [/autoit] [autoit][/autoit] [autoit]

    if (nEingabe < 1 || nEingabe > nExitProgramm)
    {
    printf_s("Keine g\x81ltige Eingabe!\nBitte einen Men\x81punkt zwischen 1 und %i ausw\x84hlen!", nExitProgramm);
    continue;
    }
    printf_s("\n");

    [/autoit] [autoit][/autoit] [autoit]

    if (nEingabe == nExitMenue)
    return;

    [/autoit] [autoit][/autoit] [autoit]

    if (nEingabe == nExitProgramm)
    exit(EXIT_SUCCESS);

    [/autoit] [autoit][/autoit] [autoit]

    if (nEingabe == nClearScreen)
    system("cls");

    [/autoit] [autoit][/autoit] [autoit]

    if (nEingabe == 1)
    {
    function();
    continue;
    }

    [/autoit] [autoit][/autoit] [autoit]

    va_start(argptr, function);
    strArgs = va_arg(argptr, char*);
    for (nPointer; nPointer < nZaehler; nPointer++)
    {
    newFunction = va_arg(argptr, void*);
    strArgs = va_arg(argptr, char*);

    if (nEingabe == nPointer)
    {
    newFunction();
    break;
    }
    }
    va_end(argptr);
    } while (1);
    }

    [/autoit]

    EDIT: Habe nun noch hinzugefügt,dass bei Release Konfiguration (wenn bei showMenu der letzte Parameter "NULL" ist) das Programm nicht mehr abstürtzt. Hatte nur bei den **char Variablen auf NULL geprüft. Gefixt.

  • Danke für die nette Funktion. Werde ich vielleicht mal einsetzen.
    Dein letztes Update habe ich zufällig heute schon gemacht, da es anders bei mir sowieso nicht funktionierte und auch nicht funktionieren kann. Hab auch noch das Löschen der Console nach jedem Befehlsaufruf engebaut.
    Auf alle Fälle eine nützliche Funktion um kleinen Programmen schnell ein nettes Menü zu verpassen! :thumbup:

  • Danke für die nette Funktion. [ ... ]
    Auf alle Fälle eine nützliche Funktion um kleinen Programmen schnell ein nettes Menü zu verpassen!

    Danke. Endlich mal ein Feedback zu meinen Quellcodes :D Sonst werden wie nur still gedownloadet mehr nicht.
    Aber freut mich wenn es dir hilft. Oder auch anderen. War auch nur so dahin geschrieben. Eigentlich achte ich mittlererweile sehr auf ungarische notation und programmiere auch fast nur noch auf englisch. Aber das war eben einfach nur fürs Studium damit es schöner aussieht :)