switch/case in C umsetzten

fimbel4_DE

Mitglied
Hallo zusammen,
Ich habe ein Java Programm geschrieben, dass mithilfe einer Array List Kontakte speichern, löschen, verschieben, ... usw. kann. Nun will ich das gleiche Programm in C umsetzen. Bisher habe ich nur in Java Programmiert also fällt mir dies nicht gerade leicht.
Hier zumal das soweit fertige Java Programm (bin natürlich auch hier offen für verbesserungen):

Java:
import java.io.Console;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Basics {

    static Scanner sc = new Scanner(System.in);
    static List<String> ContactList = new ArrayList<String>();
    static String ContactName;
    static String ContactNameInsert;
    static boolean beenden = false;
    
//***********************************************************************************************************************************************
    public static void main(String args[]) { // main Methode

        ausgabeMenu();
        defineCase();
    }

//***********************************************************************************************************************************************
    public static void ausgabeMenu() { // Ausgabe des Menüs
        System.out.println();
        System.out.println();

        System.out.println("****************************");
        System.out.println("Contactlist app");
        System.out.println("Commands:");
        System.out.println("l - list contacts");
        System.out.println("a - add contact");
        System.out.println("c - clear list");
        System.out.println("i - insert contact");
        System.out.println("d - delete contact");
        System.out.println("q - quit program");
        System.out.println("h - print this help");
        System.out.println("****************************");

        System.out.println();
        System.out.println();
    }

//************************************************************************************************************************************************
    public static void defineCase() {

        while (beenden != true) {

            System.out.println("Enter command: -h- for help.");
            String command = sc.nextLine();
            switch (command) {

            case "a":
                addContact();
                break;
            case "c":
                clearList();
                break;
            case "h":
                ausgabeMenu();
                break;
            case "d":
                deleteContact();
                break;
            case "l":
                listContacts();
                break;
            case "i":
                insertContact();
                break;
            case "q":
                quitProgramm();
            default:
                System.err.println("Command not available. Please enter -h- for help.");
            }
        }
//************************************************************************************************************************************************
    }

    public static void addContact() { // ein Kontakt wird erstellt und in der ArrayListe gespeichert.
        System.out.println();
        System.out.println();
        System.out.println("********ADD CONTACT*************");

        System.out.print("Please enter Contact Name:");

        ContactName = sc.nextLine();

        ContactList.add(ContactName);

        System.out.println("Contact created successfully");

        System.out.println("********ADD CONTACT*************");
        System.out.println();
        System.out.println();

    }
// ************************************************************************************************************************************************

    public static void clearList() {

        if (!ContactList.isEmpty()) {

            System.out.println();
            System.out.println();
            System.out.println("********CLEAR LIST*************");
            ContactList.clear();
            System.out.println("Contact list successfully cleared.");
            System.out.println("********CLEAR LIST*************");
            System.out.println();
            System.out.println();

        } else
            System.err.print("No contacts have been saved yet. Please enter -a- to create a contact");
    }
// ************************************************************************************************************************************************   

    public static void deleteContact() {// Ein Kontakt wird an beliebiger stelle entfernt.

        try {
            System.out.println();
            System.out.println();

            System.out.println("********DELETE CONTACT*************");

            System.out.println("Which contact should be deleted? Please type in the Number.");

            listContacts();

            String ContactNumberStr = sc.next();
            int ContactNumber = Integer.parseInt(ContactNumberStr);

            ContactList.remove(ContactNumber);

            System.out.println("Contact successfully deleted");

            System.out.println("********DELETE CONTACT*************");
            System.out.println();
            System.out.println();

        } catch (IndexOutOfBoundsException e) {
            System.err.println(" ERROR: Contact does not exist.");

        } catch (NumberFormatException e) {
            System.err.println("ERROR: Please enter a valid number");
        }

    }
// ************************************************************************************************************************************************

    public static void listContacts() { // Der Inhalt der ArrayList wird ausgegeben.
        
        System.out.println();
        System.out.println();
        System.out.println("********CONTACT LIST*************");

        if (!ContactList.isEmpty()) {

            for (int i = 0; i < ContactList.size(); i++) {

                System.out.println(i + " " + ContactList.get(i));

            }
        } else
            System.err.println("No contacts have been saved yet. Please enter -a- to create a contact");

        System.out.println("********CONTACT LIST*************");
        System.out.println();
        System.out.println();
    }
    // ************************************************************************************************************************************************

    public static void quitProgramm() { // Das Programm wird beendet und die ArrayListe wird geleert.
        System.out.println();
        System.out.println();

        System.out.println("********************************");
        System.out.println("The program was terminated");
        System.out.println("********************************");
        System.out.println();
        System.out.println();
        ContactList.clear();
        beenden = true;
        System.exit(1);

    }
    // ************************************************************************************************************************************************

    public static void insertContact() { // Kontakte werden auf einer bestimmten Position gespeichert.
        if (ContactList.size() != 0) {
            try {
                System.out.println();
                System.out.println();

                System.out.println("********INSERT CONTACT*************");

                System.out.print("Please enter Contact Name:");

                ContactNameInsert = sc.nextLine();

                System.out.println("Where do you want to insert the contact?");
                listContacts();

                String ContactOrderNumberStr = sc.next();
                int ContactOrderNumber = Integer.parseInt(ContactOrderNumberStr);

                ContactList.add(ContactOrderNumber, ContactNameInsert);

                System.out.println("Contact successfully added.");

                System.out.println("********INSERT CONTACT*************");
                System.out.println();
                System.out.println();

            } catch (IndexOutOfBoundsException e) {
                System.err.println(" ERROR: Contact does not exist.");

            } catch (NumberFormatException e) {
                System.err.println("ERROR: Please enter a valid number");
            }

        } else
            System.err.println("No contacts have been saved yet. Please add contacts first");
    }

    // ************************************************************************************************************************************************

}


Hier habe ich es so gemacht, dass ich verschiedene Methoden mithilfe von switch/case ansteuern konnte durch ein simples Menü.
Ich habe dies auch in C Probiert und bin kläglich daran gescheitert.
Kann mir da jemand Tipps geben die mir vielleicht weiterhelfen könnten?

Hier mein bisheriger C Code (ist bisher noch nicht viel):

C:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

//float ContactList[];
//int beenden = 1;
//char command[2];
//***********************************************************************************************************************************************
void defineCase() {

}
//***********************************************************************************************************************************************
void ausgabeMenu() {

    printf("*************************\n");
    printf("Contactlist app\n");
    printf("Commands:\n");
    printf("l - list contacts\n");
    printf("a - add contact\n");
    printf("c - clear list\n");
    printf("i - insert contact\n");
    printf("d - delete contact\n");
    printf("q - quit programm\n");
    printf("h - print this help\n");
    printf("**************************\n");

}
//***********************************************************************************************************************************************
void listContacts() {

}
//***********************************************************************************************************************************************
void addContact() {

}
//***********************************************************************************************************************************************
void clearList() {

}
//***********************************************************************************************************************************************
int main(int argc, char *argv[]) {

    ausgabeMenu();
    defineCase();

}
//***********************************************************************************************************************************************

Vielen Dank vorab
 
K

kneitzel

Gast
Also in C hast Du kein switch auf strings. Aber in Deinem Menü ist es ja immer nur ein Zeichen und so ein char ist unter dem Strich auch nur eine Zahl -> Damit kannst Du denn ein switch nutzen.

Solltest Du aber mal auf ein switch von Strings zurück kommen müssen: Da bleibt Dir in erster Linie nur ein if else if else if .... else Konstrukt mit Stringvergleichen (z.B. strcmp Aufrufen).

Ein Workaround, der auch möglich sein könnte: Du kannst natürlich eine hash Funktion nutzen um aus Strings eine Zahl zu machen. Dies birgt aber die Gefahr, dass zwei Strings den gleichen Hash Wert haben. Also wenn Deine Hash Funktion ist, dass Du die Werte der einzelnen Zeichen addierst, dann hätte "ab" den gleichen Hash Wert wie "ba". (Hash-Funktionen berücksichtigen daher oft auch die Position mit und so ... ändert aber nichts an der Thematik.)
 

mihe7

Top Contributor
Solltest Du aber mal auf ein switch von Strings zurück kommen müssen: Da bleibt Dir in erster Linie nur ein if else if else if .... else Konstrukt mit Stringvergleichen (z.B. strcmp Aufrufen).
Eine andere Möglichkeit wäre, den Index in einem Array zu bestimmen und darauf den switch loszulassen, wobei man dann auch ein Funktionsarray verwenden und sich den switch sparen könnte...
 
K

kneitzel

Gast
Eine andere Möglichkeit wäre, den Index in einem Array zu bestimmen und darauf den switch loszulassen, wobei man dann auch ein Funktionsarray verwenden und sich den switch sparen könnte...
Ja natürlich. Das hatte ich jetzt gar nicht so im Blick. Die üblichen Methoden, um switche zu ersetzen, sind natürlich auch alle denkbar.

Und die Idee mit einem Index in einem Array finde ich auch sehr interessant als Ersatz für eine hash Funktion (Zumal diese auch keine Probleme mit möglichen Überlagerungen hat.)
 
K

kneitzel

Gast
C kennt eine Switch/Case-Konstruktion: http://openbook.rheinwerk-verlag.de...en_007.htm#mj0af5093d2964d1c56cc647d1612e2a56 (der Autor des Buchs soll aber nicht ganz unproblematisch sein)
Ja, aber eben nicht auf Strings. Wenn man sich die Seite anschaut, dann nutzt er einmal ein int und dann später einen char (Wobei das beides einfache Zahlen sind wenn man so will). Also muss man zusehen, dass man diesen Datentyp nutzt.

Der Link zeigt aber sehr schön, wie dies bei einem Menü funktionieren kann, denn genau das ist ja auch das Beispiel bei ihm. Er zeigt sogar komplett, wie das mit der Berechnung funktionieren könnte ohne diese ganzen Funktionen :)
 

fimbel4_DE

Mitglied
Hallo,
erstmal vielen Dank für die Antworten. Habe mein Problem auch gelöst bekommen :)
Code:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>

//float ContactList[];
int beenden = 0;
char command;

//***********************************************************************************************************************************************
void ausgabeMenu() {

    printf("*************************\n");
    printf("Contactlist app\n");
    printf("Commands:\n");
    printf("l - list contacts\n");
    printf("a - add contact\n");
    printf("c - clear list\n");
    printf("i - insert contact\n");
    printf("d - delete contact\n");
    printf("q - quit programm\n");
    printf("h - print this help\n");
    printf("**************************\n");

}


void insertContact() {

}

//***********************************************************************************************************************************************
void quitProgramm() {
    printf("\n");
    printf("\n");
    printf("********************************\n");
    printf("The program was terminated\n");
    printf("********************************\n");
    printf("\n");
    printf("\n");
    beenden = 1;
    exit(0);

}

//***********************************************************************************************************************************************
void deleteContact() {

}

//***********************************************************************************************************************************************
void listContacts() {

}
//***********************************************************************************************************************************************
void addContact() {

}
//***********************************************************************************************************************************************
void clearList() {

}
//***********************************************************************************************************************************************
void defineCase() {

    while (beenden == 0) {
        printf("Please enter a command:\n");

        scanf(&command);


        switch (command) {
        case 'a':
            addContact();
            break;
        case 'l':
            listContacts();
            break;
        case 'c':
            clearList();
            break;
        case 'i':
            insertContact();
            break;
        case 'd':
            deleteContact();
            break;
        case 'q':
            quitProgramm();
            break;
        case 'h':
            ausgabeMenu();
            break;
        }

    }

}
//***********************************************************************************************************************************************
int main(int argc, char *argv[]) {
    ausgabeMenu();
    defineCase();
}
//***********************************************************************************************************************************************

Wenn ich das Programm nun mit der Methode ausführe die jetzt schon funktioniert. Also die quitProgramm Methode, verhält sich die Ausgabe wie folgt:

Die Ausgabe ist komplett leer und erst wenn ich die befehl q eingebe starte das Programm damit die Methode ausgabeMenu auszuführen und dann die Methode quitProgramm.
Für mich sieht es so aus als würde direkt scanf losfeuern vor allen anderen.
Kann mir jemand sagen warum das so ist un wie ich das verhindern kann?
 
K

kneitzel

Gast
Dein scanf Aufruf ist falsch und beim Übersetzen hättest Du eigentlich eine entsprechende Warnung bekommen müssen.

Und bei mir war dann nicht die Ausgabe komplett leer sondern er hat mich massiv mit "Please enter a command" zugemüllt, so dass die Ausgabe davor auch nicht sichtbar war.

Die scanf zeile sollte natürlich erst einen Format String bekommen. Da Du ein char lesen willst, muss dieser Strind einfach %c sein:
C:
scanf("%c", &command);

Damit läuft es dann zumindest bei mir (unter Linux, nachdem ich auch den include auf conio.h gelöscht habe).
 

fimbel4_DE

Mitglied
Hmm.. Interessant. Danke auf jeden Fall.
Hab das jetzt so umgestellt wie du geschrieben hast, aber das Problem habe ich immer noch...
Nichts Passiert bis ich einen Befehl eingebe...
 
K

kneitzel

Gast
Also ich habe keine Windows C++ Umgebung zur Hand. Wenn es am puffern liegt, dann sollte ein
C:
fflush(stdout);
Nach einem Block der Ausgabe entsprechend funktionieren. Aber ich kenne das mit dem Puffern von stdout nur bis eben ein newline kommt und die kommen ja.

Wie übersetzt und startest Du es denn? Evtl. ist da irgendwo etwas zu finden...
 

fimbel4_DE

Mitglied
Ich glaube ich habe die Lösung.
Die Ausgabe funktioniert, nur läuft sie in eine Endlosschleife, was ich nicht bemerkt habe weil wie gesagt meine Ausgabe komplett leer gefegt war. Nun habe ich aber mal ohne jeglichen befehl einzugeben mein Programm geschlossen und siehe da: ca. 100000 poppt "Please enter a command" in der Ausgabe auf.

Jetzt weiss ich zumindest wo ich dran arbeiten muss!
Danke!
 
K

kneitzel

Gast
Das war ja das Verhalten auch bei mir, so die scanf Funktion nicht richtig genutzt wurde. Die hat aber dann mit der Anpassung bei mir entsprechend funktioniert. Da wäre halt wichtig, wie Du da dein Programm baust und startest - nicht dass evtl. ein altes Binary genommen wurde oder so.

Bei mir ist alles in test.c,
übersetzen tue ich alles mit gcc -o test test.c
Und dann der Start mit einem einfachen ./test auf der Kommandozeile.

Sollte prinzipiell bei Dir nicht groß anders sein, der Compiler ist ggf nicht gcc sondern ein anderer und die Parameter können etwas anders sein. Und Windows startet Binaries auch direkt aus dem aktuellen Verzeichnis, so dass nur ein test zum Start eingegeben werden müsste.
 

fimbel4_DE

Mitglied
Das ist jetzt sehr merkwürdig.
Hatte bisher immer in der C Umgebung von Eclipse getestet etc.
Jetzt habe ich das Programm über cmd Compilieren lassen und ausgeführt und da klappt jetzt alles wie gewollt.
 

Neue Themen


Oben