Parameterübergabe an die main-Funktion

Kommandozeilenparameter

Kommandozeilenparameter sind ein oft gesehener Weg um einem Programm Werte zu übergeben. Doch wie kann man so etwas in C realisieren? Da der Eintrittspunkt in unser Programm immer die main-Funktion ist, ist es auch nicht weiter verwunderlich, dass wir auch an dieser Stelle die in der Kommandozeile eingegebenen Werte erhalten können. Damit das funktioniert, müssen wir eine spezielle Definition für die main-Funktion verwenden, die Variablen bereitstellt in die die Kommandozeilenargumente gespeichert werden.

Eine neue main-Funktion

Die neue main-Funktion soll zwei Parameter erwarten. Der erste ist ein Integer, in den die Anzahl der übergebenen Argumente geschrieben wird, wobei die Grenze zwischen zwei Argumenten immer ein Whitespace ist. Der zweite Parameter enthält schließlich ein Array von Char-Zeigern, die auf die Werte der übergebenen Argumente zeigen. Es ist üblich die Parameter mit argc („argument count“) für die Anzahl der Argumente und argv („argument values“) zu bezeichnen. Die beiden am häufigsten verwendeten Definitionen der main-Funktion schauen deshalb auch folgendermaßen aus:

int main( int argc, char **argv  )
int main( int argc, char* argv[] )

Wie man sieht ist es auch völlig egal, ob man für die Werte der Argumente einen Doppelzeiger oder ein Array von Zeigern verwendet, da diese in C/C++ beinahe gleich behandelt werden. Eventuell ist für den einen oder anderen die zweite Variante etwas intuitiver, da man auf den ersten Blick erkennen kann, dass es sich um ein Array handelt.

Ein erstes Programm

So, jetzt können wir ein erstes Programm mit der neuen main-Funktion schreiben und geben den Wert der Variablen 'argc', also die Anzahl der übergebenen Argumente aus:

#include <stdio.h>
 
int main( int argc, char* argv[] )
{
  printf("Anzahl der Argumente: %d\n", argc);
 
  return 0;
}

Wenn wir dieses Programm jetzt kompilieren und ohne weitere Argumente ausführen, werden wir feststellen, dass wir bereits ein Argument erhalten obwohl wir keines angegeben haben. Das liegt daran, dass uns das Betriebssystem immer als erstes Argument den Namen des ausgeführten Programms mit der gesamten Pfadangabe mit der das Programm aufgerufen wurde übergibt. Jetzt fügen wir nach der Ausgabe der Anzahl der Argument noch folgende Zeile ein, um das erste Argument auszugeben:

printf("Pfad: %s\n", argv[0]); // Erstes Argument ausgeben

Wenn wir das Programm jetzt erneut kompilieren und ausführen, können wir erkennen, dass jetzt wirklich der Programmname mit dem Pfad ausgegeben wird.

Argumente erhalten

Jetzt sind wir aber endlich soweit und werden gleich auch weitere Argumente auswerten die wir erhalten. Wenn wir unser Programm erneut ausführen und ihm dieses Mal aber auch ein paar Argumente mit übergeben, können wir sehen, dass die Anzahl der Argumente tatsächlich stimmt. Falls wir es noch nicht getan haben öffnen wir jetzt also eine Konsole, wechseln in das Verzeichnis mit unserem Programm, und führen es zum Beispiel mit folgendem Befehl aus (MainParamTest müssen wir natürlich durch den wirklichen Namen der ausführbaren Datei ersetzen):

./MainParamTest -param1=bla test.h aha 123

Auf meinem Computer erhalte ich dabei folgende Ausgabe:

Anzahl der Argumente: 5
Pfad: ./MainParamTest

Wir können also erkennen, dass wir eigentlich nur die Kommandozeile auf Strings aufgeteilt bekommen, wobei die Trennung immer an der Stelle von Whitespaces erfolgt. Damit wir die übergebenen Werte jetzt auch verwenden können, brauchen wir sie nur mehr aus dem Array argv auslesen. Wichtig ist dabei, dass wir nicht über die Grenzen des Arrays hinauslesen, dessen Größe über argc bekannt ist.

Argumente ausgeben

Zum Schluss erweitern wir unser Programm noch um eine Schleife, die einfach alle erhaltenen Argumente auf die Konsole ausgibt:

#include <stdio.h>
 
int main( int argc, char* argv[] )
{
  printf("Anzahl der Argumente: %d\n", argc);
  printf("Pfad: %s\n", argv[0]); // Erstes Argument ausgeben
 
  // Die restlichen Argumente ausgeben:
  int i = 1;
  for(; i < argc; ++i)
    printf("Argument %d: %s\n", i, argv[i]);
 
  return 0;
}

Wenn wir dieses Programm jetzt gleich wie vorher aufrufen, erhalten wir jetzt eine Liste mit den übergebenen Argumenten, die auf meinem Computer zum Beispiel so ausschaut:

Anzahl der Argumente: 5
Pfad: ./MainParamTest
Argument 1: -param1=bla
Argument 2: test.h
Argument 3: aha
Argument 4: 123

Argumente verwenden

Da wir die Argumente ja meistens nicht einfach ausgeben sondern auch verwenden wollen, brauchen wir einfach nur unsere Schleife etwas ändern und statt das Argument auszugeben es auswerten, was im einfachsten Fall einen Vergleich mit einem anderen String bedeutet:

#include <stdio.h>
#include <string.h>
 
int main( int argc, char* argv[] )
{
  int i = 1;
  for(; i < argc; ++i)
  {
    if(      !strcmp( argv[i], "-enable-this" ) ) printf("'this' aktiviert.\n");
    else if( !strcmp( argv[i], "-enable-that" ) ) printf("'that' aktiviert.\n");
    else printf("Datei verwenden: %s\n", argv[i]);
  }
 
  return 0;
}

Ein Aufruf dieses Programms mit den Argumenten

./MainParamTest -enable-this file.txt

erzeugt dabei bei mir zum Beispiel folgende Ausgabe:

'this' aktiviert.
Datei verwenden: file.txt

Wie wir sehen ist es nicht unüblich alles was kein gültiges Argument ist als Dateiname zu interpretieren, da Programme oft einen oder mehrere Dateinamen als Eingabe benötigen.


Autorendiskussion