Forum: PC-Programmierung int main (int argc, char *argv[] )


von Peter (Gast)


Lesenswert?

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
void main(int argc, char *argv[])
7
{
8
  char STRING1[80];
9
  char STRING2[80];
10
11
  if (argc=1 && argv[6] == "/help") // Abfrage ob 1. Arg=/Help
12
    printf("1. Parameter ist 'help'\n");
13
  else
14
    printf("nicht gefunden");
15
16
  if (argc=2 && argv[0] == "/") 
17
    printf("2 Parameter enthält /'\n");
18
  else{
19
    printf("nicht gefunden");
20
  }
21
22
23
  getchar();
24
}

Was habe ich falsch gemacht?
MfG

von Alter Fritz (Gast)


Lesenswert?

Du kannst C-Strings nicht per "==" vergleichen. Siehe strncmp & Co.

von Frank S. (schroederde)


Lesenswert?

argc=1 ist ein Zuweisung die du bestimmt nicht willst.

von Oliver S. (oliverso)


Lesenswert?

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

von Slippin J. (gustavo_f)


Lesenswert?

argc=1

Aua, das ist eine Zuweisung und kein Vergleich!

von Alter Fritz (Gast)


Lesenswert?

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).

von Frank S. (schroederde)


Lesenswert?

argv[6] enthält mit hoher wahrscheinlickeit nicht das, was du erwartest.

von Moki (Gast)


Lesenswert?

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

von Peter (Gast)


Lesenswert?

Peter schrieb:
> if (argc=1 && argv[6] == "/help") // Abfrage ob 1. Arg=/Help

geht es dann mit:
1
if ( argc==1 && strcmp(argv[1],"/help")==0)
Peter schrieb:
> if (argc=2 && argv[0] == "/")
1
if ( argv[2][0]=='/' )

?

von Moki (Gast)


Lesenswert?

Nein.
1
if ( argc>1 && strcmp(argv[1],"/help")==0)

Das wäre richtig(er).

von Peter (Gast)


Lesenswert?

Moki schrieb:
> Das wäre richtig(er).

Stimmt, mit ==1 wäre die Bedingung ja nicht erfüllt, da es mehr als 1 
Argument gibt.

von Dirk B. (dirkb2)


Lesenswert?

argc ist immer mindestens 1, da in argv[0] der Programmname steht.

von Wilhelm M. (wimalopaan)


Lesenswert?

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)!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Und was steht da drin, wenn es nicht der Programmname ist? Auf welchem 
System hast Du das schon beobachten können?

von Wilhelm M. (wimalopaan)


Lesenswert?

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.

: Bearbeitet durch User
von 1-Off Error (Gast)


Lesenswert?

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.

von Dirk B. (dirkb2)


Lesenswert?

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].

von Wilhelm M. (wimalopaan)


Lesenswert?

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.

von Dirk B. (dirkb2)


Lesenswert?

Eigentlich ging es mir darum, dass bei argc == 1 keine weitern Argument 
vorhanden sind.

von Wilhelm M. (wimalopaan)


Lesenswert?

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.).

von Die schnellste Sau von Mexiko (Gast)


Lesenswert?


von Fritz G. (fritzg)


Lesenswert?

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:
1
lrwxrwxrwx 1 root root 6 17. Okt 01:46 /usr/bin/mdel -> mtools
2
lrwxrwxrwx 1 root root 6 17. Okt 01:46 /usr/bin/mdir -> mtools
3
lrwxrwxrwx 1 root root 4 16. Okt 13:59 /usr/bin/unpigz -> pigz
4
lrwxrwxrwx 1 root root 6 17. Okt 01:46 /usr/bin/mdu -> mtools
5
lrwxrwxrwx 1 root root 6 17. Okt 01:46 /usr/bin/mshowfat -> mtools
6
lrwxrwxrwx 1 root root 6 17. Okt 01:46 /usr/bin/mmove -> mtools
7
lrwxrwxrwx 1 root root 6 17. Okt 01:46 /usr/bin/mpartition -> mtools

von Wilhelm M. (wimalopaan)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.