Hallo Leute.
Ich habe eine Frage zu den Befehlszeilenargumenten von in main.
Und zwar möchte ich das Programm über die Konsole wie folgt aufrufen:
programmname /help /liste
und prüfen, ob das 1. Argument "/help" lautet und ob das 2. Argument
mit einem "/" anfängt. Dazu habe ich folgendes Programm geschrieben:
1
#include<stdio.h>
2
#include<stdlib.h>
3
#include<string.h>
4
5
6
voidmain(intargc,char*argv[])
7
{
8
charSTRING1[80];
9
charSTRING2[80];
10
11
if(argc=1&&argv[6]=="/help")// Abfrage ob 1. Arg=/Help
Compilerwarnungen nicht beachtet, C-Buch nicht gelesen, ...
C kennt keine Datentyp "String" o.ä. Vergleiche per eingebauten
Operatoren wie == tun daher nicht das, was du dir vorstellest.
Oliver
Korrektur: Ok, du kannst schon, nur kommt nichts Sinnvolles dabei
heraus, wenn es dir um den Inhalt der Strings und nicht nur deren
Adressen geht. Und Vergleich der Länge mit ==, nicht = (Zuweisung).
0. Die Gleichheitsprrüfung erfolgt mit "==", nicht mit "="
1. argc liefert die Anzahl der Parameter. Der Wert kann also nicht
gleich 1 und gleichzeitig gleich zwei sein.
2. String werden in C mit strcmp, nicht mit "==" geprüft.
3. Befrage Google, das hilft hier auch mit Codeschnipseln weiter:
https://www.proggen.org/doku.php?id=c:func:main:parameter
Dirk B. schrieb:> argc ist immer mindestens 1, da in argv[0] der Programmname steht.
argv[0] ist typischerweise(!) der Programm-Name, dass muss aber nicht so
sein (und das ist ein feature und kein bug)!
Rufus Τ. F. schrieb:> Und was steht da drin, wenn es nicht der Programmname ist? Auf welchem> System hast Du das schon beobachten können?
Überall.
Das wird ja vom Prozess bestimmt, der die Überlagerung mit exec()
durchführt. Also bspw. unter *nix mach die Shell ein fork() und dann
exec(). Bei Überlagerung durch exec() ist der erste Parameter der
Pfadname zur Datei mit dem executable, danach kommen argv[0], ...
entweder als variable Liste oder das C-String-Array.
Man kann bspw. argv[0] auf einen anderen C-String setzen als den
Programmnamen. Manchmal wird das benutzt, um Camouflage durchzuführen
oder damit sich das Programm anders verhält. Das ist eine häufige
Technik.
Gutes Beispiel ist busybox.
Da hast du prinzipiell zwar recht, aber trotzdem steht das erste
Kommandozeilenargument (und darum geht es im Ausgangsbeitrag) nicht
in argv[0], sondern in argv[1]. Dementsprechend bedeuten argc == 1
bzw. argc == 2 auch nicht das, was der OP sich davon erwartet.
Wilhelm M. schrieb:> Gutes Beispiel ist busybox.
Da steht dann der Programmname vom Sysmbolischen Link drin.
Da braucht busybox recht wenig verbiegen.
Beim Atari ST stand in argv[0] nichts drin (ob in jedem Fall oder nur
beim Start über die GUI habe ich vergessen).
Dennoch waren die ersten argumente ab argv[1].
Dirk B. schrieb:> Wilhelm M. schrieb:>> Gutes Beispiel ist busybox.>> Da steht dann der Programmname vom Sysmbolischen Link drin.>> Da braucht busybox recht wenig verbiegen.>> Beim Atari ST stand in argv[0] nichts drin (ob in jedem Fall oder nur> beim Start über die GUI habe ich vergessen).> Dennoch waren die ersten argumente ab argv[1].
Es geht doch gar nicht um die Kommandozeilenargumente (ab Index 1)!
Es geht darum, was in argv[0] steht. Du hast gesagt, da stände immer der
Programmname drin. Und das ist eben nicht so.
Was in argv[0] drin steht, dass bestimmt das Programm, das den
Systemaufruf exec() aufruft. Und das ist üblicherweise ein Kindprozeß
des startenden Prozesses.
Dirk B. schrieb:> Eigentlich ging es mir darum, dass bei argc == 1 keine weitern Argument> vorhanden sind.
Ja, genau, dann haben wir nur argv[0]. Und das kann(!) der Name des
Executables sein, muss aber nicht (s.o.).
Wenn das Programm von einer Unix-Shell aufgerufen wird, steht immer der
Programmname drin, bzw. der Name des Links.
Letzteres dient dazu, das Verhalten des Programmes zu ändern, z.B. bei
mtools:
Fritz G. schrieb:> Wenn das Programm von einer Unix-Shell aufgerufen wird, steht immer der> Programmname drin, bzw. der Name des Links.
Ja, das macht die Shell so (s.o.). Andere Programme können das anders
machen, es wird von POSIX/IEEE-1003.1 nicht erzwungen bzw. genau das
wollte man ermöglichen.
> Letzteres dient dazu, das Verhalten des Programmes zu ändern, z.B. bei> mtools:
s.a. oben mein Beispiel mit busybox.