Immer wenn Sie ein Programm auf einem Terminal ausführen, können Sie einige vom Programm erwartete Argumente übergeben, die während der Ausführung des Programms verwendet werden können. Hier stellt das System eine interne Einrichtung bereit, um alle vom Benutzer übergebenen Argumente beizubehalten, während das Programm ausgeführt wird. Diese Argumente sind als „Befehlszeilenargumente“ bekannt.
In diesem Tutorial werden wir das Verständnis von Befehlszeilenargumenten mit dem Arbeitsprogramm abbilden, um es auf klare und klare Weise besser zu verstehen. Aber bevor wir zum Programm springen, sollten wir wissen, wie das System Befehlszeilenargumente bereitstellt. Wie wir wissen, muss jedes C-Programm eine main()-Funktion haben, und die Möglichkeit der Befehlszeilenargumente wird von der main()-Funktion selbst bereitgestellt. Wenn unten angegeben, wird die Deklaration im Programm verwendet, und dann hat das Programm die Möglichkeit, Befehlszeilenargumente zu verwenden/manipulieren.
int main (int argc, char *argv[])
Hier ist der Parameter argc die Anzahl der gesamten Befehlszeilenargumente, die bei der Ausführung an die ausführbare Datei übergeben werden (einschließlich des Namens der ausführbaren Datei als erstes Argument). Der argv-Parameter ist das Array der Zeichenfolge jedes Befehlszeilenarguments, das bei der Ausführung an die ausführbare Datei übergeben wird. Wenn Sie neu in der C-Programmierung sind, sollten Sie zuerst verstehen, wie C-Arrays funktionieren.
Unten ist das funktionierende Programm mit Kommandozeilenargument.
#include <stdio.h> int main (int argc, char *argv[]) { int i=0; printf("\ncmdline args count=%s", argc); /* First argument is executable name only */ printf("\nexe name=%s", argv[0]); for (i=1; i< argc; i++) { printf("\narg%d=%s", i, argv[i]); } printf("\n"); return 0; }
Da unten wird ausgegeben, wenn das Programm ausgeführt wird.
$ ./cmdline_basic test1 test2 test3 test4 1234 56789 cmdline args count=7 exe name=./cmdline_basic arg1=test1 arg2=test2 arg3=test3 arg4=test4 arg5=1234 arg6=56789
In der obigen Ausgabe können wir sehen, dass die Gesamtzahl der Argumente intern vom „argc“-Parameter von main() verwaltet wird, der den Wert „7“ enthält (wobei ein Argument der Name der ausführbaren Datei und „6“ an das Programm übergebene Argumente sind). Und alle Argumentwerte werden im „argv“-Parameter von main() gespeichert, der ein Array von Zeichenketten ist. Hier speichert die Funktion main () jeden Argumentwert als Zeichenfolge. Wir können sehen, dass wir beim Iterieren über das „argv“-Array alle übergebenen Argumente im Programm abrufen können.
Es gibt eine weitere Deklaration der Funktion main(), die eine zusätzliche Möglichkeit bietet, mit Umgebungsvariablen innerhalb des Programms zu arbeiten. Wie die Argumente, die im Array argv[] verwaltet werden, verfügt die Funktion main() über eine interne Einrichtung, um alle Systemumgebungsvariablen in einem Array von Zeichenfolgen zu verwalten, die als Parameter der Funktion main() verwendet werden können. Unten ist die Deklaration.
int main (int argc, char *argv[], char **envp)
Unten ist das Arbeitsprogramm, das Kommandozeilenargumente zusammen mit Umgebungsvariablen verwendet.
#include <stdio.h> int main (int argc, char *argv[], char **env_var_ptr) { int i=0; printf("\ncmdline args count=%d", argc); /* First argument is executable name only */ printf("\nexe name=%s", argv[0]); for (i=1; i< argc; i++) { printf("\narg%d=%s", i, argv[i]); } i=0; while (*env_var_ptr != NULL) { i++; printf ("\nenv var%d=>%s",i, *(env_var_ptr++)); } printf("\n"); return 0; }
Die Ausgabe des obigen Programms ist unten angegeben.
$ ./env test1 test2 cmdline args count=3 exe name=./env arg1=test1 arg2=test2 env var1=>SSH_AGENT_PID=1575 env var2=>KDE_MULTIHEAD=false env var3=>SHELL=/bin/bash env var4=>TERM=xterm env var5=>XDG_SESSION_COOKIE=5edf27907e97deafc70d310550995c84-1352614770.691861-1384749481 env var6=>GTK2_RC_FILES=/etc/gtk-2.0/gtkrc:/home/sitaram/.gtkrc-2.0:/home/sitaram/.kde/share/config/gtkrc-2.0 env var7=>KONSOLE_DBUS_SERVICE=:1.76 env var8=>KONSOLE_PROFILE_NAME=Shell env var9=>GS_LIB=/home/sitaram/.fonts env var10=>GTK_RC_FILES=/etc/gtk/gtkrc:/home/sitaram/.gtkrc:/home/sitaram/.kde/share/config/gtkrc env var11=>WINDOWID=29360154 env var12=>GNOME_KEYRING_CONTROL=/run/user/sitaram/keyring-2Qx7DW env var13=>SHELL_SESSION_ID=f7ac2d9459c74000b6fd9b2df1d48da4 env var14=>GTK_MODULES=overlay-scrollbar env var15=>KDE_FULL_SESSION=true env var16=>http_proxy=http://10.0.0.17:8080/ env var17=>USER=sitaram env var18=>LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36: env var19=>XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0 env var20=>XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0 env var21=>SSH_AUTH_SOCK=/tmp/ssh-kIFY5HttOJxe/agent.1489 env var22=>ftp_proxy=ftp://10.0.0.17:8080/ env var23=>SESSION_MANAGER=local/Sitaram:@/tmp/.ICE-unix/1716,unix/Sitaram:/tmp/.ICE-unix/1716 env var24=>DEFAULTS_PATH=/usr/share/gconf/kde-plasma.default.path env var25=>XDG_CONFIG_DIRS=/etc/xdg/xdg-kde-plasma:/etc/xdg env var26=>DESKTOP_SESSION=kde-plasma env var27=>PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games env var28=>PWD=/home/sitaram/test_progs/cmdline env var29=>socks_proxy=socks://10.0.0.17:8080/ env var30=>KONSOLE_DBUS_WINDOW=/Windows/1 env var31=>KDE_SESSION_UID=1000 env var32=>LANG=en_IN env var33=>GNOME_KEYRING_PID=1478 env var34=>MANDATORY_PATH=/usr/share/gconf/kde-plasma.mandatory.path env var35=>UBUNTU_MENUPROXY=libappmenu.so env var36=>KONSOLE_DBUS_SESSION=/Sessions/1 env var37=>https_proxy=https://10.0.0.17:8080/ env var38=>GDMSESSION=kde-plasma env var39=>SHLVL=1 env var40=>HOME=/home/sitaram env var41=>COLORFGBG=15;0 env var42=>KDE_SESSION_VERSION=4 env var43=>LANGUAGE=en_IN:en env var44=>XCURSOR_THEME=Oxygen_White env var45=>LOGNAME=sitaram env var46=>XDG_DATA_DIRS=/usr/share/kde-plasma:/usr/local/share/:/usr/share/ env var47=>DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-mnJhMvd4jG,guid=435ddd41500fd6c5550ed8d2509f4374 env var48=>LESSOPEN=| /usr/bin/lesspipe %s env var49=>PROFILEHOME= env var50=>XDG_RUNTIME_DIR=/run/user/sitaram env var51=>DISPLAY=:0 env var52=>QT_PLUGIN_PATH=/home/sitaram/.kde/lib/kde4/plugins/:/usr/lib/kde4/plugins/ env var53=>LESSCLOSE=/usr/bin/lesspipe %s %s env var54=>XAUTHORITY=/tmp/kde-sitaram/xauth-1000-_0 env var55=>_=./env env var56=>OLDPWD=/home/sitaram/test_progs $
In der obigen Ausgabe können wir sehen, dass alle Systemumgebungsvariablen als dritter Parameter der Funktion main() abgerufen werden können, die im Programm durchlaufen und in der Ausgabe angezeigt werden.
Übergeben von Befehlszeilenargumenten zum Programmieren und Manipulieren von Argumenten
Unten ist ein Programm, das mit Befehlszeilenargumenten arbeitet.
#include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int i=0; int d; float f; long int l; FILE *file = NULL; printf("\ncmdline args count=%d", argc); /* First argument is executable name only */ printf("\nexe name=%s", argv[0]); for (i=1; i< argc; i++) { printf("\narg%d=%s", i, argv[i]); } /* Conversion string into int */ d = atoi(argv[1]); printf("\nargv[1] in intger=%d",d); /* Conversion string into float */ f = atof(argv[1]); printf("\nargv[1] in float=%f",f); /* Conversion string into long int */ l = strtol(argv[2], NULL, 0); printf("\nargv[2] in long int=%ld",l); /*Open file whose path is passed as an argument */ file = fopen( argv[3], "r" ); /* fopen returns NULL pointer on failure */ if ( file == NULL) { printf("\nCould not open file"); } else { printf("\nFile (%s) opened", argv[3]); /* Closing file */ fclose(file); } printf("\n"); return 0; }
Die Ausgabe des obigen Programms ist unten angegeben.
$ ./cmdline_strfunc 1234test 12345678 /home/sitaram/test_progs/cmdline/cmdline_strfunc.c cmdline args count=4 exe name=./cmdline_strfunc arg1=1234test arg2=12345678 arg3=/home/sitaram/test_progs/cmdline/cmdline_strfunc.c argv[1] in intger=1234 argv[1] in float=1234.000000 argv[2] in long int=12345678 File (/home/sitaram/test_progs/cmdline/cmdline_strfunc.c) opened
In der obigen Ausgabe können wir sehen, dass Befehlszeilenargumente im Programm manipuliert werden können; Alle Argumente werden als Zeichenfolge erhalten, die in Integer, Float, Long konvertiert werden kann, wie im Programm gezeigt. Sogar eine beliebige Zeichenfolge, wenn sie als Pfad einer beliebigen Datei übergeben wird, die vom Programm zur Dateiverarbeitungsoperation dieser Datei verwendet werden kann. Wir können im obigen Programm sehen, dass der Dateipfad (/home/sitaram/test_progs/cmdline/cmdline_strfunc.c ) als Befehlszeilenargument übergeben wird, das innerhalb des Programms verwendet wird, um die Datei zu öffnen und zu schließen.
Getopt()-API
Wenn wir mehr über Befehlszeilenargumente erfahren, haben wir eine sehr leistungsfähige API – getopt(). Es erleichtert Programmierern das Analysieren von Befehlszeilenoptionen. Der Programmierer kann getopt() eine Liste mit obligatorischen oder optionalen Befehlszeilenoptionen geben. Es kann bestimmen, ob die Befehlszeilenoption gemäß den vom Programm erwarteten Befehlszeilenoptionen entweder gültig oder ungültig ist. Es gibt einige getopt()-spezifische interne Variablen wie „optarg, optopt, opterr“
- Optarg :enthält einen Zeiger auf das Argument der gültigen Befehlszeilenoption
- Optopt :enthält eine Befehlszeilenoption, wenn die obligatorische Befehlszeilenoption fehlt
- Opterr :auf ungleich Null gesetzt, wenn eine ungültige Option angegeben wird oder der Wert der obligatorischen Befehlszeilenoption nicht angegeben wird
Unten ist ein grundlegendes Programm, um das Parsen von Befehlszeilenoptionen zu verstehen.
#include <stdio.h> #include <unistd.h> int main (int argc, char *argv[]) { int opt = 0; char *in_fname = NULL; char *out_fname = NULL; while ((opt = getopt(argc, argv, "i:o:")) != -1) { switch(opt) { case 'i': in_fname = optarg; printf("\nInput option value=%s", in_fname); break; case 'o': out_fname = optarg; printf("\nOutput option value=%s", out_fname); break; case '?': /* Case when user enters the command as * $ ./cmd_exe -i */ if (optopt == 'i') { printf("\nMissing mandatory input option"); /* Case when user enters the command as * # ./cmd_exe -o */ } else if (optopt == 'o') { printf("\nMissing mandatory output option"); } else { printf("\nInvalid option received"); } break; } } printf("\n"); return 0; }
Die Ausgabe des obigen Programms ist unten mit einigen Kombinationen von Befehlszeilenoptionen angegeben:
Case1: $ ./cmdline_getopt -i /tmp/input -o /tmp/output Input option value=/tmp/input Output option value=/tmp/output Case2: $ ./cmdline_getopt -i -o /tmp/output Input option value=-o Case3: $ ./cmdline_getopt -i ./cmdline_getopt: option requires an argument -- 'i' Missing mandatory input option Case4: $ ./cmdline_getopt -i /tmp/input -o ./cmdline_getopt: option requires an argument -- 'o' Input option value=/tmp/input Missing mandatory output option Case5: $ ./cmdline_getopt -k /tmp/input ./cmdline_getopt: invalid option -- 'k' Invalid option received
Im obigen Programm werden „i“ und „o“ als obligatorische Eingabe- und Ausgabebefehlszeilenoptionen für Programme verwendet, die die getopt()-API verwenden.
Wir hätten jetzt eine grundlegende Erklärung für jeden Fall, der im obigen Programm ausgeführt wird:
- In Fall1 werden beide obligatorischen Befehlszeilenoptionen mit ihren Argumenten bereitgestellt, die in den ersten beiden Fällen der Schalterbedingung des Programms richtig behandelt werden.
- In Fall 2 wird der Wert der obligatorischen Eingabeoption nicht angegeben, aber wir können sehen, dass getopt() nicht intelligent genug ist und „-o“ als Wert der Befehlszeilenoption „I“ betrachtet. Es ist kein Fehlerfall für getopt(), aber der Programmierer kann selbst Intelligenz hinzufügen, um einen solchen Fall zu handhaben.
- In Fall 3 wird nur die Befehlszeilenoption ohne ihren Wert angegeben und dies ist eine obligatorische Option, daher würde getopt() in diesem Fall „?“ zurückgeben und die Variable „optopt“ wird auf „i“ gesetzt, um den Wert der obligatorischen Eingabeoption zu bestätigen fehlt.
- In Case4 fehlt der Wert der obligatorischen Ausgabeoption.
- In Fall 5 wird eine ungültige Befehlszeilenoption angegeben, die keine obligatorische oder optionale Befehlszeilenoption ist. In diesem Fall hat getopt() „?“ zurückgegeben und optopt ist nicht gesetzt, da es sich um ein unbekanntes Zeichen handelt, das von getopt() nicht erwartet wurde.