Forum: PC-Programmierung Parameter ausgabe schlägt fehl


von Hickhack0 (Gast)


Lesenswert?

Servus Beisammen,

ich hab gerade angefangen mich mit C++ zu spielen. Dazu hab ich mir 
Dev-C++ runtergelanden und recht Erfolgreich das gute "Hello 
World"-Programm geschrieben.
Meine 2. Aufgabe sollte es sein, ein Programm mit Parametern aufzurufen 
und diese erstmal unbearbeitet wieder ausgeben zu lassen.
Hier scheitere ich dann auch schon wieder. Google will mir auch nicht 
sagen was ich falsch mache und sonst kenne ich niemanden, der mir nen 
Tipp gibt. Aber vielleicht finde ich ja hier den ein oder anderen guten 
Rat.

Mein Code sieht wie folgt aus:
1
#include <stdio.h>
2
3
main(int argc, char *argv[])
4
{
5
 printf("Parameteranzahl: %d \n", argc);
6
 for (int i = 0; i < argc; i++)
7
 {
8
  printf(" Parameter %d: %s \n", i, *argv);
9
 }
10
 printf(" Parameter 0: %c \n", *argv[0]);
11
 printf(" Parameter 1: %c \n", *argv[1]);
12
 printf(" Parameter 2: %c \n", *argv[2]);
13
}

starte ich das Programm mit: *unbenannt1.exe abc 123*
erhalte ich folgendes Output
1
Parameteranzahl: 3
2
 Parameter 0: unbenannt1.exe
3
 Parameter 1: unbenannt1.exe
4
 Parameter 2: unbenannt1.exe
5
 Parameter 0: u
6
 Parameter 1: a
7
 Parameter 2: 1

ich probiere schon seit Stunden rum, komme aber einfach nicht auf die 
gewünschte Ausgabe:
1
Parameteranzahl: 3
2
 Parameter 0: unbenannt1.exe
3
 Parameter 1: abc
4
 Parameter 2: 123

Kann mir bitte jemand helfen und sagen was ich falsch mache?

von Karl H. (kbuchegg)


Lesenswert?

Hickhack0 schrieb:

>  printf("Parameteranzahl: %d \n", argc);
>  for (int i = 0; i < argc; i++)
>  {
>   printf(" Parameter %d: %s \n", i, *argv);

*argv ändert sich nicht dadurch, dass du i hochzählst :-)
1
 for (int i = 0; i < argc; i++)
2
 {
3
   printf(" Parameter %d: %s \n", i, argv[i] );
4
 }
5
 printf(" Parameter 0: %s \n", argv[0]);
6
 printf(" Parameter 1: %s \n", argv[1]);
7
 printf(" Parameter 2: %s \n", argv[2]);
8
}

von Peter (Gast)


Lesenswert?

1
main(int argc, char *argv[])
2
{
3
 printf("Parameteranzahl: %d \n", argc);
4
 for (int i = 0; i < argc; i++)
5
 {
6
  printf(" Parameter %d: %s \n", i, argv[i]);
7
 }
8
 printf(" Parameter 0: %c \n", argv[0]);
9
 printf(" Parameter 1: %c \n", argv[1]);
10
 printf(" Parameter 2: %c \n", argv[2]);
11
}

von Hickhack0 (Gast)


Lesenswert?

Ich danke euch, es funktioniert!!!
nur jetzt bin ich verwirrt!

argv[] beinhaltet doch eine Speicheradresse. Diese als string ausgegeben 
ergibt das was ich will?!
erst *argv[] leitet mich doch dann auf den Speicherplatz mit meinem 
Inhalt weiter?!
so hab ich das zumindest hier 
(http://de.wikibooks.org/wiki/C-Programmierung:_Zeiger) verstanden!

Kann mir das jetz mal eben einer kurz erklären?

von Peter (Gast)


Lesenswert?

> erst *argv[] leitet mich doch dann auf den Speicherplatz mit meinem
> Inhalt weiter?!
ja. Aber printf will für die String ausgabe ein Zeiger und nicht den 
"wert".

von Hickhack0 (Gast)


Lesenswert?

und warum funktioniert dann "i"? i ist doch nicht weniger Variable als 
*argv[]
oder anders: &i entspricht argv[].

oder ist für den Compiler "i" genauso ein Zeiger mit einer 
Speicheradresse im Inhalt wie es bei "argv[]" der Fall ist?
Würde in meiner Logik gerade heißen: printf braucht speicheradressen als 
input, keine Werte.

Ist zwar gerade kompliziert für mich zu verstehen, aber irendwie machts 
doch von gewissen Seiten her betrachtet Sinn...
Andererseits kann das auch nicht stimmen, da ich ja ansonsten um den 
Wert von "i" zu verändern "*i" setzen müsste. (also *i=0 und nicht i=0)
??????

von Karl H. (kbuchegg)


Lesenswert?

Hickhack0 schrieb:
> und warum funktioniert dann "i"? i ist doch nicht weniger Variable als
> *argv[]

*argv[] ist keine Variable. argv[][] ist die Variable. Der

> oder anders: &i entspricht argv[].

Nein.

> oder ist für den Compiler "i" genauso ein Zeiger mit einer

i ist kein Zeiger. Du schmeisst da einiges durcheinander.

> Würde in meiner Logik gerade heißen: printf braucht speicheradressen als
> input, keine Werte.

printf braucht das als Argument, was in der Formatliste steht.
Steht dort ein %d , dann muss das entsprechende Argument ein int-Wert 
sein.
Steht dort ein %s, dann muss das entsprechende Argument eine Adresse 
sein, an der der String beginnt.
Es sind die Angaben im Formatstring, die printf leiten, wie Argumente zu 
bewerten sind. Daher ist es auch ausserordentlich wichtig, dass die 
Angaben im Formatstring und die tatsächlichen Argumente übereinstimmen. 
(Und da das fehleranfällig und schlecht wartbar ist, hat man sich in C++ 
mit den streams dafür einen komplett anderen Mechanismus einfallen 
lassen)

   printf( "%d", 5 );
   printf( "%d", 8 + 4 );
   printf( "%d", i );
   printf( "%d", 2 * ( i + j ) );

In der Formatliste steht durch das %d, dass das zugehörige Argument ein 
int ist. Wie dieser int zustande kommt, ist unerheblich. Hauptsache ein 
int.

    char * Text1 = "Juhu";
    char   Text2[] = "Moin";

    printf( "%s", "Hallo" );
    printf( "%s", Text1 );
    printf( "%s", Text2 );
    printf( "%s", Text2 + 2 );

In der Formatliste steht durch das %s, dass das zugehörige Argument die 
Adresse eines Strings ist. Der String wird ab der angegegebenen Adresse, 
bis zum Auftreten eines '\0' Bytes im String ausgegeben.

Du hast

     char * argv[]

also ein Array von Zeigern, wobei jeder Zeiger die Adresse eines Strings 
enthält


           argv
          +-----------+               +------------------+
          |     o-------------------->| "Argument1"      |
          +-----------+               +------------------+
          |     o------------------+    +--------------------+
          +-----------+            +--->| "Argument2"        |
          |     o------------+          +--------------------+
          +-----------+      |     +-------------------+
          | NULL      |      +---->| "Argument3"       |
          +-----------+            +-------------------+

Du willst nacheinander jeden Zeiger an printf übergeben, weil printf ja 
im Falle von %s die Startadresse des Strings haben möchte und diese 
Startadressen ja im Array gespeichert sind.

      for( i = 0; i < argc; ++i )
        printf( "%s", argv[i] );

argv[i] gibt den i-ten Zeiger aus dem Array, also die Startadresse des 
i-ten Strings. Genau das was %s haben möchte.

Besorg dir ein Buch. Online Tutorien brings in den seltesten Fällen und 
auf deinem Level ist Google wenig hilfreich.

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.