In der heutigen »Look&Feel«-Zeit scheinen Kommandozeilenprogramme schon ein wenig veraltet zu sein. Die nächste Generation wird mit Begriffen wie »Kommandozeile« oder »Konsole« wohl nichts mehr anzufangen wissen.
13 Kommandozeilenargumente
Wenn aber z. B. ältere Programme überholt werden müssen, wird der Umgang mit der Kommandozeile wieder wichtig. Bei Betriebssystemen wie Linux, UNIX oder FreeBSD ist es nach wie vor üblich (teilweise sogar unerlässlich), sehr viel mit einer Kommandozeile zu arbeiten.
Beim Schreiben eines Konsolenprogramms für Linux/UNIX oder MS-DOS (Eingabeaufforderung) sind Kommandozeilenparameter immer noch eines der wichtigsten Konzepte. Da Konsolenprogramme keine grafische Oberfläche besitzen, stellt die Kommandozeile die wichtigste Schnittstelle zwischen dem Anwender und dem Programm dar.
Hinweis |
Dem Programm werden Argumente beim Aufruf übergeben. Unter MS-Windows können Sie hierfür die Eingabeaufforderung cmd.exe verwenden. Unter Linux genügt eine einfache Konsole bzw. Shell. Sofern Sie Entwicklungsumgebungen (IDEs) verwenden, müssen Sie Kommandozeilenargumente anders übergeben. Viele Entwicklungsumgebungen bieten hierfür beim Menü Ausführen noch ein Untermenü Parameter oder so ähnlich (abhängig von der IDE), um die Argumente noch vor dem Programmstart festzulegen. Mehr dazu finden Sie auf der Buch-CD. |
13.1 Argumente an die Hauptfunktion übergeben 

Um einem Programm beim Start Argumente zu übergeben, wird eine parametrisierte Hauptfunktion benötigt. Ihre Syntax sieht wie folgt aus:
int main(int argc, char *argv[]) { /* ... */ }
Diese Hauptfunktion main() besitzt zwei Parameter mit den Namen argc und argv. Die Namen dieser Parameter sind so nicht vorgeschrieben. Sie können genauso gut Folgendes schreiben:
int main(int argumenten_zaehler, char *argumenten_vektor[]) { /* ... */ }
Der erste Parameter beinhaltet die Anzahl von Argumenten, die dem Programm beim Start übergeben wurden. Dabei handelt es sich um einen Integerwert. Im zweiten Parameter stehen die einzelnen Argumente. Diese werden als Strings in einer Stringtabelle gespeichert. Folgendes Beispiel demonstriert dies:
/* argument.c */ #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int i; for(i=0; i < argc; i++) { printf("argv[%d] = %s ", i, argv[i]); printf("\n"); } return EXIT_SUCCESS; }
Das Listing wurde z. B. unter dem Namen argument.c gespeichert und anschließend übersetzt. Wenn Sie das Programm starten, wird auf dem Bildschirm der Programmname ausgegeben:
argv[0] = argument
Starten Sie das Programm jetzt nochmals mit folgender Eingabe (argument sei wieder der Programmname):
argument Hallo Welt
Abbildung 13.1 zeigt die Ausgabe, die Sie dann erhalten.
Abbildung 13.1 Argumente aus der Kommandozeile auswerten
In argv[0] befindet sich meistens der Programmname, das muss aber nicht so sein. Ein Beispiel:
char *argv_for_new_app[] = {"ganzAndererName", ....argumente}; char *application = "/bin/bash"; execve(application, argv_for_new_app, envp);
Somit ist in argv[0] der Bash nun eben »ganzAndererName« zu lesen. Das ist u. a. ein effektiver Workaround für DOS/Windows-Plattformen, die keine Symlinks haben (d. h., manche Programme erkennen ihre Funktion an argv[0]).
Die einzelnen Argumente, die dem Programm übergeben werden, müssen immer durch mindestens ein Leerzeichen getrennt sein. Wenn Sie zum Beispiel
argument HalloWelt
schreiben, wäre die Ausgabe stattdessen:
argv[0] = argument argv[1] = HalloWelt
Der Parameter int argc zählt die Anzahl der Strings, die dem Programm beim Aufruf mitgegeben wurden. Dazu ein Beispiel:
/* arg_counter.c */ #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { printf("Insgesamt %d Argumente\n", argc-1); printf("Letztes Argument: %s\n", argv[argc-1]); return EXIT_SUCCESS; }
Bei diesem Beispiel werden die Anzahl der Argumente und das letzte Argument ausgegeben. Als Programmaufruf dient etwa:
argument abc xyz
In der Stringtabelle char **argv befinden sich die Strings, die Sie in Abbildung 13.2 sehen.
Abbildung 13.2 Inhalt der Stringtabelle »argv«
Falls dezimale Werte anstelle von Strings als Argumente übergeben werden, handelt es sich dabei weiterhin um Strings. Wird der dezimale Wert benötigt, so muss der String erst in einen solchen Wert konvertiert werden. Hier sehen Sie ein Beispiel einer solchen Konvertierung:
/* calc.c */ #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { int i, j ; long y, erg; if(argc < 4) { printf("Benötige mindestens 4 Argumente!\n"); printf("Aufruf: %s <zahl><op><zahl> ...\n", *argv); return EXIT_FAILURE; } /* 1.Zahl in einen Integer konvertieren*/ erg = strtol(argv[1], NULL, 10); if( erg == 0 ) { printf("Keine gültige Ganzzahl ... \n"); return EXIT_FAILURE; } for(i = 1; i < argc-1; i += 2) { for(j=i+1; j < i+2; j++) { y = strtol(argv[i+2], NULL, 10); if( y == 0 ) { printf("Keine gültige Ganzzahl ... \n"); printf("argc: %d (%s)?!\n", i+2, argv[i+2]); return EXIT_FAILURE; } if(strcmp(argv[j],"+") == 0) erg += y; else if(strcmp(argv[j],"-") == 0) erg -= y; else if(strcmp(argv[j], "x") == 0) erg *= y; else if(strcmp(argv[j],"/") == 0) erg/=y; else { printf("Ungültiger Operand: %s\n", argv[j]); return EXIT_FAILURE; } } } printf("%ld\n",erg); return EXIT_SUCCESS; }
Damit lassen sich einfache Rechenoperationen ausführen. Im Folgenden soll eine solche Eingabe demonstriert werden (der Programmname sei hierfür calc):
calc 5 + 5 - 9 x 10 / 2
Intern sieht diese Eingabe so aus:
Abbildung 13.3 Einzelne Argumente für Rechenoperationen auswerten
Hier wurden zehn Argumente eingegeben, wobei jedes dieser zehn Argumente ein Stringende-Zeichen (\0) besitzt. Somit besitzt der Parameter int argc in der Funktion main() den Wert 9. Beachten Sie bei der Eingabe, dass nach jedem Zeichen ein Leerzeichen folgt. Folgendes würde nicht funktionieren:
calc 5+5-9x10/2 /* falsch, nur ein Argument*/
Mit
if(argc < 4) { printf("Benötige mindestens 4 Argumente!\n"); printf("Aufruf: %s <zahl><op><zahl> ...\n", *argv); return EXIT_FAILURE; }
wird getestet, ob weniger als vier Argumente eingegeben wurden. Falls dies zutrifft, wird eine entsprechende Fehlermeldung auf dem Bildschirm ausgegeben und das Programm beendet.
Wenn die Mindestanzahl von Argumenten gegeben ist, folgt als Nächstes die Konvertierung der Argumente:
erg = strtol(argv[1], NULL, 10);
Hierbei wird mit der Funktion strtol der String in argv[1] in eine dezimale Zahl konvertiert. Im ersten Fall wird der String "5" in den Integerwert 5 umgewandelt. Die Funktion strtol() ist in der Headerdatei <stdlib.h> deklariert. Mehr zu strtol() und weiteren ähnlichen Funktionen erwartet Sie in Kapitel 20, »Weitere Headerdateien und ihre Funktionen (ANSI C)«.
Weiter mit dem Programmablauf bei den for-Schleifen:
for(i = 1; i < argc-1; i += 2) { for(j=i+1; j < i+2; j++) { y = strtol(argv[i+2], NULL, 10);
Die erste for-Schleife durchläuft die ungeraden Zahlen des Feldindex, in dem sich (bei richtiger Anwendung des Programms) dezimale Zahlen befinden: [1]="5", [3]="5", [5]="9", [7]="10", [9]="2". Die zweite for-Schleife durchläuft die geraden Zahlen und dient den Operatoren +, -, * und / ([2]="+", [4]="–", [6]="*", [8]="/"). Danach bekommt die Variable y den dezimalen Wert der Zeichenkette argv[3], der wiederum mit strtol() konvertiert wird.
Jetzt erfolgt die Auswertung des Operators:
if(strcmp(argv[j],"+") == 0) erg += y;
Entspricht argv[2] dem Additionszeichen "+"? In dem Fall ist das zweite Argument tatsächlich das Zeichen "+". Daher kann jetzt der erste Wert (zweites Argument) mit dem zweiten Wert (viertes Argument) addiert (drittes Argument) werden. Der Wert wird in der Variablen erg zwischengespeichert. Genauso läuft dies mit den nächsten Zahlen und Operatoren ab, bis keine Argumente (Zahlen oder Operatoren) mehr vorhanden sind.
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.