|
![ein Kapitel weiter](../weiter.gif)
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 weiter](../weiter.gif)
© 2001,2002 Jürgen Wolf
|