ein Kapitel zurück                                           ein Kapitel weiter

Dieser Taschenrechner, so wie wir Ihn im Kapitel zuvor geschrieben haben, macht natürlich wenig Sinn. Sinnvoller und sehr häufig verwendet ist es Schalter auszuwerten die in der Kommandozeile miteingeben werden. Beispielsweise...

rm --help

Gibt die Hilfe des Programms rm, zum löschen von Dateien und Verzeichnisse aus. Bei dieser Hilfe handelt es sich meist um eine kurze Beschreibung welche Optionen (Schalter) mit angegeben werden können. Beispielsweise wird mit.....

rm -rf verzeichnis

das ganze Verzeichnis Rekursiv ohne Nachfrage gelöscht. Wir wollen ein einfaches Beispiel verwenden. Auf jedem System gibt es doch das Programm echo was die Eingabe wieder auf die Standardausgabe wiederholt. Beispielsweise...

echo Hallo Welt

...gibt Hallo Welt auf dem Bildschirm aus. Wir wollen nun unser eigenes echo, myecho, schreiben womit wir den Text Spiegelverkehrt, in Gross-oder Kleinbuchstaben ausgeben können. Folgende Schalter wollen wir dabei verwenden......

void show_help(void)
{
printf("\nProgrammaufruf : myecho [OPTION] STRING\n");
printf("Programm gibt den Text in gewünschter Form auf dem Bildschirm aus\n");
printf("\nFolgende Optionen stehen Ihnen zur Verfügung : \n\n");
printf("\t-r Text wird Spiegelverkehrt ausgegeben\n");
printf("\t-g Text wird in Grossbuchstaben ausgegeben\n");
printf("\t-s Text wird in Kleinbuchstaben ausgegeben\n");
printf("\t-h Dieser Text\n");
printf("\t-v Versionsnummer\n\n");
}

Hier der komplette Quellcode dazu.......

/*Download:arg4.c*/
#include <stdio.h>
#include <string.h>

enum{ FALSE,TRUE};

void show_help(void)
{
printf("\nProgrammaufruf : echo [OPTION] STRING\n");
printf("Programm gibt den Text in gewünschter Form auf dem Bildschirm aus\n");
printf("\nFolgende Optionen stehen Ihnen zur Verfügung : \n\n");
printf("\t-r Text wird Spiegelverkehrt ausgegeben\n");
printf("\t-g Text wird in Grossbuchstaben ausgegeben\n");
printf("\t-s Text wird in Kleinbuchstaben ausgegeben\n");
printf("\t-h Dieser Text\n");
printf("\t-v Versionsnummer\n\n");
}

int getopt(char *argument,char *option)
{
if( argument[0]=='-' && argument[1]==option[0] )
return TRUE;
return FALSE;
}

void spiegeln(char *string)
{
char *reverse=string;
while(*reverse++);
while(*reverse-- != *string)
printf("%c",*reverse);
printf("\n");
}

void larger(char *string)
{
char *large=string;
while(*large)
printf("%c",(isalpha(*large))?toupper(*large++):*large++);
printf("\n");
}

void smaller(char *string)
{
char *small=string;
while(*small)
printf("%c",(isalpha(*small))?tolower(*small++):*small++);
printf("\n");
}


int main(int argc, char *argv[])
{
int counter=3;
char buffer[4096];
if(argc == 1 || getopt(argv[1],"h") == TRUE )
{
show_help();
exit(0);
}
else if(getopt(argv[1],"v") == TRUE)
{
printf("Version 1.0\n");
exit(0);
}
else if(argc < 3)
{
show_help();
exit(0);
}

/*Ab argv[2] bis argv[n] alle Elemente in buffer*/
strcpy(buffer,argv[2]);
while(argv[counter]!=NULL)
{
strcat(buffer, " ");
strcat(buffer, argv[counter++]);
}

if(getopt(argv[1],"r") == TRUE)
spiegeln(buffer);
else if(getopt(argv[1],"g") == TRUE)
larger(buffer);
else if(getopt(argv[1],"s") == TRUE)
smaller(argv[2]);
else
show_help();
return 0;
}

Als erstes Kernstück in diesem Programm dient unser Selbstgeschriebene Funktion getopt()...

int getopt(char *argument,char *option)
{
   if( argument[0]=='-' && argument[1]==option[0] )
     return TRUE;
   return FALSE;
}


...mit der wir überprüfen ob der String mit dem Schalterzeichen '-' beginnt und ob für option einen Option vorhanden ist.....

getopt(argv[1],"s") == TRUE

In diesem Beispiel überprüfen wir Beispielsweise ob der Schalter 's' verwendet wurde. Ist alles OK geben wir TRUE zurück. Anderfalls geben wir FALSE zurück. Alle anderen Funktionen dienen nur zu Verzierung des Programms welches sie natürlich weiterausbauen können.

Manch einer dürfte mit dieser Schalterauswertung zufrieden sein. Aber vielleicht sollte man diese Schalterauswertung noch etwas flexibler Gestalten. Damit ist gemeint das auch Eingaben wie zum Beispiel.....

myecho Hallo Welt wie gehts -r

...funktionieren sollten. Genauso sollte es möglich sein mehrere Optionen auf einem Schalter zu laden, wie.....

myecho -rg Hallo Welt wie gehts

Also den Text Spiegeln und in Grossbuchstaben umwandeln. Um das Problem mit der Schreibweise, Schalter vor String oder String vor Schalter zu lösen, laufen wir die Liste der Argumente einfach zweimal durch......

/*Download:arg5.c*/
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
char String_arg[4096]="";
char schalter[3];
int i;
/*Zuerst den Schalter suchen*/
for(i=1; i<argc; i++)
if(argv[i][0]=='-')
strcpy(schalter,argv[i]);

/*Jetzt die restlich Argumente einsammeln*/
for(i=1; i<argc; i++)
if(argv[i][0]!='-'){
strcat(String_arg,argv[i]);
strcat(String_arg," ");
}

printf("Schalter : %s\n",schalter);
printf("String : %s\n",String_arg);

return 0;
}

Bei diesem Beispiel ist es auch egal wenn sie schreiben......

myecho Hallo Welt -r wie gehts

Und um nun mehrere Schalter gleichzeitig auszuwerten müssen sie jetzt nur noch den String schalter auswerten. Dies machen sie am besten nach dem beide Durchläufe fertig sind.

Hierzu nun die Verbesserte Version, wo sich den Schalter an einer X-beliebigen Stelle angeben können.....

/*Download:arg6.c*/
#include <stdio.h>
#include <string.h>

enum{OFF,SMALL,LARGE};
static int flag=OFF;
char String_arg[4096]="";
char schalter[5];
void spiegeln(char *);
void larger(char *);
void smaller(char *);

void show_help(void)
{
printf("\nProgrammaufruf : echo [OPTION] STRING\n");
printf("Programm gibt den Text in gewünschter Form auf dem Bildschirm aus\n");
printf("\nFolgende Optionen stehen Ihnen zur Verfügung : \n\n");
printf("\t-r Text wird Spiegelverkehrt ausgegeben\n");
printf("\t-g Text wird in Grossbuchstaben ausgegeben\n");
printf("\t-s Text wird in Kleinbuchstaben ausgegeben\n");
printf("\t-h Dieser Text\n");
printf("\t-v Versionsnummer\n\n");
}

void getopt(char *schalter)
{
if(strcmp(schalter, "-r") == 0){
flag=OFF;
spiegeln(String_arg);
}
else if(strcmp(schalter, "-rg") == 0 || strcmp(schalter, "-gr") == 0){
flag=LARGE;
spiegeln(String_arg);
}
else if(strcmp(schalter, "-rs") == 0 || strcmp(schalter, "-sr") == 0){
flag=SMALL;
spiegeln(String_arg);
}
else if(strcmp(schalter, "-g") == 0){
flag=LARGE;
larger(String_arg);
}
else if(strcmp(schalter, "-s") == 0){
flag=SMALL;
smaller(String_arg);
}
else if(strcmp(schalter, "-h") == 0){
flag=OFF;
show_help();
}
else if(strcmp(schalter, "-v") == 0)
printf("Version 1.1\n");
else
show_help();
}

void spiegeln(char *string)
{
char *reverse=string;
char temp[4096]="";
while(*reverse++);
if(flag==LARGE){
while(*reverse--!= *string)
strncat(temp,reverse,1);
larger(temp);
}
else if(flag==SMALL){
while(*reverse--!= *string)
strncat(temp,reverse,1);
smaller(temp);
}
else{
while(*reverse-- != *string)
printf("%c",*reverse);
}
printf("\n");
}

void larger(char *string)
{
char *large=string;
while(*large)
printf("%c",(isalpha(*large))?toupper(*large++):*large++);
printf("\n");
}

void smaller(char *string)
{
char *small=string;
while(*small)
printf("%c",(isalpha(*small))?tolower(*small++):*small++);
printf("\n");
}

int main(int argc, char *argv[])
{
int i;
/*Zuerst den Schalter suchen*/
for(i=1; i<argc; i++)
if(argv[i][0]=='-')
strcpy(schalter,argv[i]);

/*Jetzt die restlich Argumente einsammeln*/
for(i=1; i<argc; i++)
if(argv[i][0]!='-'){
strcat(String_arg,argv[i]);
strcat(String_arg," ");
}

getopt(schalter);

printf("Schalter : %s\n",schalter);
printf("String : %s\n",String_arg);

return 0;
}

Dreh-und-Angelpunkt des Programms ist die Funktion getopt und das Flag flag, was wir mit den Werten OFF für einen einfachen Schalter und SMALL für einen Schalter mit Kleinschreibung und Spiegelung des Textes belegen können. Außerdem haben wir noch das Flag LARGE für Großschreibung und Spiegelung des Textes.

Und schon haben wir mit nur ein paar Modifikationen, unserem Programm zu einer Benutzerfreundlicheren Schnittstelle verholfen. Das sollte übrigens auch immer das oberste Gebot eines Programmierers sein, wenn dieser Programme für andere entwickelt.

Ich hoffe das ich mit diesem Kapitel einige Anregungen zu diesem Thema gemacht habe.

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf