Kapitel 15 Kommandozeilenargumente
In der heutigen »Look&Feel«-Zeit scheinen Kommandozeilen-Programme schon ein wenig veraltet zu sein. Die nächste Generation wird mit Begriffen wie »Kommandozeile« oder »Konsole« wohl nichts mehr anzufangen wissen.
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 (teilw. sogar unerlässlich), sehr viel mit einer Kommandozeile zu arbeiten.
Beim Schreiben eines Konsolen-Programms für Linux/UNIX oder MS-DOS (–Eingabeaufforderung) sind Kommandozeilenparameter immer noch eines der wichtigsten Konzepte. Da Konsolen-Programme 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 kann dabei das alte MS-DOS herhalten. Die MS-DOS-Eingabeaufforderung von MS-Windows ist dafür aber auch geeignet. Unter Linux genügt eine einfache Konsole bzw. Shell. Sofern Sie Entwicklungsumgebungen (IDEs) verwenden, müssen Sie Kommandozeilen-Argumente 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.
|
15.1 Argumente an die Hauptfunktion
 
Um einem Programm beim Start Argumente zu übergeben, wird eine parametrisierte Hauptfunktion benötigt. Hierzu die Syntax:
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 schreiben:
int main(int argumenten_zaehler, char **argumenten_vektor)
Der erste Parameter beinhaltet die Anzahl von Argumenten, welche 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. Starten Sie das Programm, 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
Die jetzige Ausgabe lautet:
 Hier klicken, um das Bild zu Vergrößern
Abbildung 15.1
Argumente aus der Kommandozeile auswerten
In argv[0] befindet sich meistens der Programmname, muss aber nicht 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 mit mindestens einem Leerzeichen getrennt sein. Zum Beispiel mit
argument HalloWelt
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 folgende Strings:
 Hier klicken, um das Bild zu Vergrößern
Abbildung 15.2
Inhalt der Stringtabelle argv
Falls dezimale Werte anstatt Strings als Argumente übergeben werden, handelt es sich dabei weiterhin um Strings. Wird der dezimale Wert benötigt, so muss dieser erst in einen solchen konvertiert werden. Hierzu das 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ültig 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("%d\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:
 Hier klicken, um das Bild zu Vergrößern
Abbildung 15.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 neun. 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 dieser und weiteren ähnlichen Funktionen erwartet Sie in Kapitel 22, Weitere Headerdateien und ihre Funktionen.
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 Feldindexes, 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.
|