mikrocontroller.net

Forum: PC-Programmierung Parameter ausgabe schlägt fehl


Autor: Hickhack0 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <stdio.h>

main(int argc, char *argv[])
{
 printf("Parameteranzahl: %d \n", argc);
 for (int i = 0; i < argc; i++)
 {
  printf(" Parameter %d: %s \n", i, *argv);
 }
 printf(" Parameter 0: %c \n", *argv[0]);
 printf(" Parameter 1: %c \n", *argv[1]);
 printf(" Parameter 2: %c \n", *argv[2]);
}

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

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

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)
 for (int i = 0; i < argc; i++)
 {
   printf(" Parameter %d: %s \n", i, argv[i] );
 }
 printf(" Parameter 0: %s \n", argv[0]);
 printf(" Parameter 1: %s \n", argv[1]);
 printf(" Parameter 2: %s \n", argv[2]);
}

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
main(int argc, char *argv[])
{
 printf("Parameteranzahl: %d \n", argc);
 for (int i = 0; i < argc; i++)
 {
  printf(" Parameter %d: %s \n", i, argv[i]);
 }
 printf(" Parameter 0: %c \n", argv[0]);
 printf(" Parameter 1: %c \n", argv[1]);
 printf(" Parameter 2: %c \n", argv[2]);
}

Autor: Hickhack0 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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".

Autor: Hickhack0 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)
??????

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.